X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fmain.cpp;h=a1b21cc4d0f65b1cf1fb3ad2cba4787ab2648ec0;hb=941ff7c62ac6b94d08e349025428ca1b2e0b6f3a;hp=75e882e998672a27bebcbd7087b3f2205c75424d;hpb=f5394d3bac1d27ed34b58cc3253e0ace8a30283e;p=inkscape.git diff --git a/src/main.cpp b/src/main.cpp index 75e882e99..a1b21cc4d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,3 @@ -#define __MAIN_C__ - /** \file * Inkscape - an ambitious vector drawing program * @@ -15,6 +13,8 @@ * Pawel Palucha * Bryce Harrington * ... and various people who have worked with various projects + * Jon A. Cruz + * Abhishek Sharma * * Copyright (C) 1999-2004 authors * Copyright (C) 2001-2002 Ximian, Inc. @@ -47,6 +47,8 @@ #endif /* Not def: POPT_TABLEEND */ #include +#include +#include #include #include #include @@ -56,6 +58,10 @@ #include "gc-core.h" +#ifdef AND +#undef AND +#endif + #include "macros.h" #include "file.h" #include "document.h" @@ -94,14 +100,9 @@ #include #ifdef WIN32 -//#define REPLACEARGS_ANSI -//#define REPLACEARGS_DEBUG - #include "registrytool.h" - #include "extension/internal/win32.h" using Inkscape::Extension::Internal::PrintWin32; - #endif // WIN32 #include "extension/init.h" @@ -113,7 +114,6 @@ using Inkscape::Extension::Internal::PrintWin32; #define bind_textdomain_codeset(p,c) #endif -#include "application/application.h" #include "main-cmdlineact.h" #include "widgets/icon.h" #include "ui/widget/panel.h" @@ -143,6 +143,7 @@ enum { SP_ARG_EXPORT_PS, SP_ARG_EXPORT_EPS, SP_ARG_EXPORT_PDF, + SP_ARG_EXPORT_LATEX, #ifdef WIN32 SP_ARG_EXPORT_EMF, #endif //WIN32 @@ -181,6 +182,7 @@ static gchar *sp_export_dpi = NULL; static gchar *sp_export_area = NULL; static gboolean sp_export_area_drawing = FALSE; static gboolean sp_export_area_page = FALSE; +static gboolean sp_export_latex = FALSE; static gchar *sp_export_width = NULL; static gchar *sp_export_height = NULL; static gchar *sp_export_id = NULL; @@ -205,7 +207,6 @@ static gboolean sp_query_width = FALSE; static gboolean sp_query_height = FALSE; static gboolean sp_query_all = FALSE; static gchar *sp_query_id = NULL; -static int sp_new_gui = FALSE; static gboolean sp_shell = FALSE; static gboolean sp_vacuum_defs = FALSE; @@ -224,6 +225,7 @@ static void resetCommandlineGlobals() { sp_export_area = NULL; sp_export_area_drawing = FALSE; sp_export_area_page = FALSE; + sp_export_latex = FALSE; sp_export_width = NULL; sp_export_height = NULL; sp_export_id = NULL; @@ -372,6 +374,11 @@ struct poptOption options[] = { N_("Export document to a PDF file"), N_("FILENAME")}, + {"export-latex", 0, + POPT_ARG_NONE, &sp_export_latex, SP_ARG_EXPORT_LATEX, + N_("Export PDF/PS/EPS without text. Besides the PDF/PS/EPS, a LaTeX file is exported, putting the text on top of the PDF/PS/EPS file. Include the result in LaTeX like: \\input{latexfile.tex}"), + NULL}, + #ifdef WIN32 {"export-emf", 'M', POPT_ARG_STRING, &sp_export_emf, SP_ARG_EXPORT_EMF, @@ -465,80 +472,109 @@ gchar * blankParam = g_strdup(""); #ifdef WIN32 /** - * Return the directory of the .exe that is currently running + * Set up the PATH and PYTHONPATH environment variables on Windows + * @param exe Inkscape executable directory in UTF-8 */ -static Glib::ustring _win32_getExePath() +static void _win32_set_inkscape_env(gchar const *exe) { - char exeName[MAX_PATH+1]; - // TODO these should use xxxW() calls explicitly and convert UTF-16 <--> UTF-8 - GetModuleFileName(NULL, exeName, MAX_PATH); - char *slashPos = strrchr(exeName, '\\'); - if (slashPos) { - *slashPos = '\0'; - } - Glib::ustring s = exeName; - return s; -} - -/** - * Set up the PATH and PYTHONPATH environment variables on - * win32 - */ -static int _win32_set_inkscape_env(const Glib::ustring &exePath) -{ - // TODO use g_getenv() and g_setenv() that use filename encoding, which is UTF-8 on Windows - - char *oldenv = getenv("PATH"); - Glib::ustring tmp = "PATH="; - tmp += exePath; - tmp += ";"; - tmp += exePath; - tmp += "\\python;"; - tmp += exePath; - tmp += "\\python\\Scripts;"; // for uniconv.cmd - tmp += exePath; - tmp += "\\perl"; - if(oldenv != NULL) { - tmp += ";"; - tmp += oldenv; + gchar const *path = g_getenv("PATH"); + gchar const *pythonpath = g_getenv("PYTHONPATH"); + + gchar *python = g_build_filename(exe, "python", NULL); + gchar *scripts = g_build_filename(exe, "python", "Scripts", NULL); + gchar *perl = g_build_filename(exe, "python", NULL); + gchar *pythonlib = g_build_filename(exe, "python", "Lib", NULL); + gchar *pythondll = g_build_filename(exe, "python", "DLLs", NULL); + + // Python 2.x needs short paths in PYTHONPATH. + // Otherwise it doesn't work when Inkscape is installed in Unicode directories. + // g_win32_locale_filename_from_utf8 is the GLib wrapper for GetShortPathName. + // Remove this once we move to Python 3.0. + gchar *python_s = g_win32_locale_filename_from_utf8(python); + gchar *pythonlib_s = g_win32_locale_filename_from_utf8(pythonlib); + gchar *pythondll_s = g_win32_locale_filename_from_utf8(pythondll); + + gchar *new_path; + gchar *new_pythonpath; + if (path) { + new_path = g_strdup_printf("%s;%s;%s;%s;%s", exe, python, scripts, perl, path); + } else { + new_path = g_strdup_printf("%s;%s;%s;%s", exe, python, scripts, perl); } - _putenv(tmp.c_str()); - - oldenv = getenv("PYTHONPATH"); - tmp = "PYTHONPATH="; - tmp += exePath; - tmp += "\\python;"; - tmp += exePath; - tmp += "\\python\\Lib;"; - tmp += exePath; - tmp += "\\python\\DLLs"; - if(oldenv != NULL) { - tmp += ";"; - tmp += oldenv; + if (pythonpath) { + new_pythonpath = g_strdup_printf("%s;%s;%s;%s", + python_s, pythonlib_s, pythondll_s, pythonpath); + } else { + new_pythonpath = g_strdup_printf("%s;%s;%s", + python_s, pythonlib_s, pythondll_s); } - _putenv(tmp.c_str()); - return 0; + g_setenv("PATH", new_path, TRUE); + g_setenv("PYTHONPATH", new_pythonpath, TRUE); + + /* + printf("PATH = %s\n\n", g_getenv("PATH")); + printf("PYTHONPATH = %s\n\n", g_getenv("PYTHONPATH")); + + gchar *p = g_find_program_in_path("python"); + if (p) { + printf("python in %s\n\n", p); + g_free(p); + } else { + printf("python not found\n\n"); + }*/ + + g_free(python); + g_free(scripts); + g_free(perl); + g_free(pythonlib); + g_free(pythondll); + + g_free(python_s); + g_free(pythonlib_s); + g_free(pythondll_s); + + g_free(new_path); + g_free(new_pythonpath); } #endif -/** - * Add INKSCAPE_EXTENSIONDIR to PYTHONPATH so that extensions in users home - * can find inkex.py et al. (Bug #197475) - */ -static int set_extensions_env() +static void set_extensions_env() { - char *oldenv = getenv("PYTHONPATH"); - Glib::ustring tmp = INKSCAPE_EXTENSIONDIR; - if (oldenv != NULL) { - tmp += G_SEARCHPATH_SEPARATOR; - tmp += oldenv; + gchar const *pythonpath = g_getenv("PYTHONPATH"); + gchar *extdir; + gchar *new_pythonpath; + +#ifdef WIN32 + extdir = g_win32_locale_filename_from_utf8(INKSCAPE_EXTENSIONDIR); +#else + extdir = g_strdup(INKSCAPE_EXTENSIONDIR); +#endif + + // On some platforms, INKSCAPE_EXTENSIONDIR is not absolute, + // but relative to the directory that contains the Inkscape executable. + // Since we spawn Python chdir'ed into the script's directory, + // we need to obtain the absolute path here. + if (!g_path_is_absolute(extdir)) { + gchar *curdir = g_get_current_dir(); + gchar *extdir_new = g_build_filename(curdir, extdir, NULL); + g_free(extdir); + g_free(curdir); + extdir = extdir_new; } - g_setenv("PYTHONPATH", tmp.c_str(), TRUE); - return 0; -} + if (pythonpath) { + new_pythonpath = g_strdup_printf("%s" G_SEARCHPATH_SEPARATOR_S "%s", + extdir, pythonpath); + g_free(extdir); + } else { + new_pythonpath = extdir; + } + g_setenv("PYTHONPATH", new_pythonpath, TRUE); + g_free(new_pythonpath); + //printf("PYTHONPATH = %s\n", g_getenv("PYTHONPATH")); +} /** * This is the classic main() entry point of the program, though on some @@ -555,61 +591,53 @@ main(int argc, char **argv) #endif #ifdef WIN32 - /* - Set the current directory to the directory of the - executable. This seems redundant, but is needed for - when inkscape.exe is executed from another directory. - We use relative paths on win32. - HKCR\svgfile\shell\open\command is a good example - */ - Glib::ustring homedir = _win32_getExePath(); - // TODO these should use xxxW() calls explicitly and convert UTF-16 <--> UTF-8 - SetCurrentDirectory(homedir.c_str()); - _win32_set_inkscape_env(homedir); + gchar *exedir = g_strdup(win32_getExePath().data()); + _win32_set_inkscape_env(exedir); + +# ifdef ENABLE_NLS + // obtain short path to executable dir and pass it + // to bindtextdomain (it doesn't understand UTF-8) + gchar *shortexedir = g_win32_locale_filename_from_utf8(exedir); + gchar *localepath = g_build_filename(shortexedir, PACKAGE_LOCALE_DIR, NULL); + bindtextdomain(GETTEXT_PACKAGE, localepath); + g_free(shortexedir); + g_free(localepath); +# endif + g_free(exedir); + // Don't touch the registry (works fine without it) for Inkscape Portable gchar const *val = g_getenv("INKSCAPE_PORTABLE_PROFILE_DIR"); if (!val) { RegistryTool rt; rt.setPathInfo(); } -#endif - - // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) - Gtk::Main::init_gtkmm_internals(); - - // Bug #197475 - set_extensions_env(); - - /** - * Call bindtextdomain() for various machines's paths - */ -#ifdef ENABLE_NLS -#ifdef WIN32 - Glib::ustring localePath = homedir; - localePath += "\\"; - localePath += PACKAGE_LOCALE_DIR; - bindtextdomain(GETTEXT_PACKAGE, localePath.c_str()); -#else -#ifdef ENABLE_BINRELOC +#elif defined(ENABLE_NLS) +# ifdef ENABLE_BINRELOC bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR("")); -#else +# else bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); +# endif #endif -#endif + + // the bit below compiles regardless of platform +#ifdef ENABLE_NLS // Allow the user to override the locale directory by setting // the environment variable INKSCAPE_LOCALEDIR. - char *inkscape_localedir = getenv("INKSCAPE_LOCALEDIR"); + char const *inkscape_localedir = g_getenv("INKSCAPE_LOCALEDIR"); if (inkscape_localedir != NULL) { bindtextdomain(GETTEXT_PACKAGE, inkscape_localedir); } -#endif + // common setup bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); - -#ifdef ENABLE_NLS textdomain(GETTEXT_PACKAGE); #endif + set_extensions_env(); + + // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) + Gtk::Main::init_gtkmm_internals(); + LIBXML_TEST_VERSION Inkscape::GC::init(); @@ -619,8 +647,7 @@ main(int argc, char **argv) gboolean use_gui; #ifndef WIN32 - // TODO use g_getenv() and g_setenv() that use filename encoding, which is UTF-8 on Windows - use_gui = (getenv("DISPLAY") != NULL); + use_gui = (g_getenv("DISPLAY") != NULL); #else use_gui = TRUE; #endif @@ -646,6 +673,7 @@ main(int argc, char **argv) || !strncmp(argv[i], "--export-eps", 12) || !strcmp(argv[i], "-A") || !strncmp(argv[i], "--export-pdf", 12) + || !strncmp(argv[i], "--export-latex", 14) #ifdef WIN32 || !strcmp(argv[i], "-M") || !strncmp(argv[i], "--export-emf", 12) @@ -683,10 +711,15 @@ main(int argc, char **argv) } #endif // WIN32 - /// \todo Should this be a static object (see inkscape.cpp)? - Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui); + int retcode; + + if (use_gui) { + retcode = sp_main_gui(argc, (const char **) argv); + } else { + retcode = sp_main_console(argc, (const char **) argv); + } - return app.run(); + return retcode; } @@ -990,7 +1023,7 @@ void sp_process_file_list(GSList *fl) g_warning("Specified document %s cannot be opened (does not exist or not a valid SVG file)", filename); } else { if (sp_vacuum_defs) { - vacuum_document(doc); + doc->vacuumDocument(); } if (sp_vacuum_defs && !sp_export_svg) { // save under the name given in the command line @@ -1007,9 +1040,9 @@ void sp_process_file_list(GSList *fl) Inkscape::XML::Node *repr; rdoc = sp_repr_document_new("svg:svg"); repr = rdoc->root(); - repr = sp_document_root(doc)->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD); + repr = doc->getRoot()->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD); sp_repr_save_rebased_file(repr->document(), sp_export_svg, SP_SVG_NS_URI, - doc->base, sp_export_svg); + doc->getBase(), sp_export_svg); } if (sp_export_ps) { do_export_ps_pdf(doc, sp_export_ps, "image/x-postscript"); @@ -1163,15 +1196,15 @@ do_query_dimension (SPDocument *doc, bool extent, Geom::Dim2 const axis, const g return; } } else { - o = SP_DOCUMENT_ROOT(doc); + o = doc->getRoot(); } if (o) { - sp_document_ensure_up_to_date (doc); + doc->ensureUpToDate(); SPItem *item = ((SPItem *) o); // "true" SVG bbox for scripting - Geom::OptRect area = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect area = item->getBounds(item->i2doc_affine()); if (area) { Inkscape::SVGOStringStream os; if (extent) { @@ -1186,15 +1219,12 @@ do_query_dimension (SPDocument *doc, bool extent, Geom::Dim2 const axis, const g } } -static void -do_query_all (SPDocument *doc) +static void do_query_all(SPDocument *doc) { - SPObject *o = NULL; - - o = SP_DOCUMENT_ROOT(doc); + SPObject *o = doc->getRoot(); if (o) { - sp_document_ensure_up_to_date (doc); + doc->ensureUpToDate(); do_query_all_recurse(o); } } @@ -1203,11 +1233,11 @@ static void do_query_all_recurse (SPObject *o) { SPItem *item = ((SPItem *) o); - if (o->id && SP_IS_ITEM(item)) { - Geom::OptRect area = item->getBounds(sp_item_i2doc_affine(item)); + if (o->getId() && SP_IS_ITEM(item)) { + Geom::OptRect area = item->getBounds(item->i2doc_affine()); if (area) { Inkscape::SVGOStringStream os; - os << o->id; + os << o->getId(); os << "," << area->min()[Geom::X]; os << "," << area->min()[Geom::Y]; os << "," << area->dimensions()[Geom::X]; @@ -1244,12 +1274,12 @@ sp_do_export_png(SPDocument *doc) SPObject *o_area = NULL; if (sp_export_id && sp_export_area_drawing) { o = doc->getObjectById(sp_export_id); - o_area = SP_DOCUMENT_ROOT (doc); + o_area = doc->getRoot(); } else if (sp_export_id) { o = doc->getObjectById(sp_export_id); o_area = o; } else if (sp_export_area_drawing) { - o = SP_DOCUMENT_ROOT (doc); + o = doc->getRoot(); o_area = o; } @@ -1297,9 +1327,9 @@ sp_do_export_png(SPDocument *doc) } // write object bbox to area - sp_document_ensure_up_to_date (doc); + doc->ensureUpToDate(); Geom::OptRect areaMaybe; - sp_item_invoke_bbox((SPItem *) o_area, areaMaybe, sp_item_i2d_affine((SPItem *) o_area), TRUE); + static_cast(o_area)->invoke_bbox( areaMaybe, static_cast(o_area)->i2d_affine(), TRUE); if (areaMaybe) { area = *areaMaybe; } else { @@ -1315,16 +1345,16 @@ sp_do_export_png(SPDocument *doc) if (sp_export_area) { /* Try to parse area (given in SVG pixels) */ gdouble x0,y0,x1,y1; - if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &x0, &y0, &x1, &y1) == 4) { + if (sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &x0, &y0, &x1, &y1) != 4) { g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area); return; } area = Geom::Rect(Geom::Interval(x0,x1), Geom::Interval(y0,y1)); } else if (sp_export_area_page || !(sp_export_id || sp_export_area_drawing)) { /* Export the whole page: note: Inkscape uses 'page' in all menus and dialogs, not 'canvas' */ - sp_document_ensure_up_to_date (doc); + doc->ensureUpToDate(); Geom::Point origin (SP_ROOT(doc->root)->x.computed, SP_ROOT(doc->root)->y.computed); - area = Geom::Rect(origin, origin + sp_document_dimensions(doc)); + area = Geom::Rect(origin, origin + doc->getDimensions()); } // set filename and dpi from options, if not yet set from the hints @@ -1418,8 +1448,8 @@ sp_do_export_png(SPDocument *doc) gchar *path = 0; if (filename_from_hint) { //Make relative paths go from the document location, if possible: - if (!g_path_is_absolute(filename) && doc->uri) { - gchar *dirname = g_path_get_dirname(doc->uri); + if (!g_path_is_absolute(filename) && doc->getURI()) { + gchar *dirname = g_path_get_dirname(doc->getURI()); if (dirname) { path = g_build_filename(dirname, filename, NULL); g_free(dirname); @@ -1518,6 +1548,12 @@ static void do_export_ps_pdf(SPDocument* doc, gchar const* uri, char const* mime (*i)->set_param_bool("textToPath", FALSE); } + if (sp_export_latex) { + (*i)->set_param_bool("textToLaTeX", TRUE); + } else { + (*i)->set_param_bool("textToLaTeX", FALSE); + } + if (sp_export_ignore_filters) { (*i)->set_param_bool("blurToBitmap", FALSE); } else {