Code

don't need svg 'load and save'. in fact, it doesnt fit
[inkscape.git] / src / main.cpp
index 165316cd2a614c9438f389511161b147e3cc997a..c3d368bc536c69c1b8b93c622aefd15e0dded73f 100644 (file)
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
-// Putting the following in main.cpp appears a natural choice.
-
-/** \mainpage The Inkscape Source Code Documentation
- * While the standard doxygen documentation can be accessed through the links
- * in the header, the following documents are additionally available to the
- * interested reader.
- *
- * \section groups Main directory documentation
- * Inkscape's classes and files in the main directory can be grouped into
- * the following categories:
- *
- * - \subpage ObjectTree - inkscape's SVG canvas
- * - \subpage Tools - the tools UI
- * - \subpage UI - inkscape's user interface
- * - \subpage XmlTree - XML backbone of the document
- * - \subpage Rendering - rendering and buffering
- * - \subpage OtherServices - what doesn't fit in the above
- *
- * See also the <a href="dirs.html">other directories</a> until doxygen
- * allows setting links to those doc files.
- *
- * \section extlinks Links to external documentation
- *
- * \subsection liblinks External documentation on libraries used in inkscape
- *
- * <a href="http://www.gtkmm.org/gtkmm2/docs/">Gtkmm</a>
- * <a href="http://www.gtkmm.org/gtkmm2/docs/reference/html/dir_000003.html">atkmm</a>
- * <a href="http://www.gtkmm.org/gtkmm2/docs/reference/html/dir_000009.html">gdkmm</a>
- * <a href="http://www.gtkmm.org/gtkmm2/docs/reference/html/dir_000007.html">pangomm</a>
- * <a href="http://libsigc.sourceforge.net/libsigc1_2/reference/html/modules.html">libsigc++</a>
- * <a href="http://www.gtk.org/api/">GTK+</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/gdk-pixbuf/index.html">gdk-pixbuf</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/gobject/index.html">GObject</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/atk/index.html">atk</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/pango/index.html">pango</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/gnome-vfs-2.0/">GnomeVFS</a>
- * <a href="http://libsigc.sourceforge.net/libsigc2/docs/index.html">libsigc</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/ORBit/index.html">ORBit</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/libbonobo/index.html">bonobo</a>
- * <a href="http://developer.gnome.org/doc/API/2.0/bonobo-activation/index.html">bonobo-activation</a>
- * <a href="http://xmlsoft.org/XSLT/html/libxslt-lib.html#LIBXSLT-LIB">libxslt</a>
- * <a href="http://xmlsoft.org/html/index.html">libxml2</a>
- *
- * \subsection stdlinks External standards documentation
- *
- * <a href="http://www.w3.org/TR/SVG/">SVG1.1</a>
- * <a href="http://www.w3.org/TR/SVG12/">SVG1.2</a>
- * <a href="http://www.w3.org/TR/SVGMobile/">SVGMobile</a>
- * <a href="http://www.w3.org/Graphics/SVG/Test/">SVGTest</a>
- * <a href="http://www.libpng.org/pub/png/">PNG</a>
- * <a href="http://www.w3.org/TR/xslt">XSLT</a>
- * <a href="http://partners.adobe.com/public/developer/ps/index_specs.html">PS</a>
- * <a href="http://developer.gnome.org/projects/gup/hig/">Gnome-HIG</a>
- */
-
-/** \page ObjectTree Object Tree Classes and Files
- * Inkscape::ObjectHierarchy [\ref object-hierarchy.cpp, \ref object-hierarchy.h]
- * - SPObject [\ref sp-object.cpp, \ref sp-object.h, \ref object-edit.cpp, \ref sp-object-repr.cpp]
- *   - SPDefs [\ref sp-defs.cpp, \ref sp-defs.h]
- *   - SPFlowline [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h]
- *   - SPFlowregionbreak [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h]
- *   - SPGuide [\ref sp-guide.cpp, \ref sp-guide.h]
- *   - SPItem [\ref sp-item.cpp, \ref sp-item.h, \ref sp-item-notify-moveto.cpp, \ref sp-item-rm-unsatisfied-cns.cpp, \ref sp-item-transform.cpp, \ref sp-item-update-cns.cpp, ]
- *     - SPFlowdiv [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h]
- *     - SPFlowpara [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h]
- *     - SPFlowregion [\ref sp-flowregion.cpp, \ref sp-flowregion.h]
- *     - SPFlowregionExclude [\ref sp-flowregion.cpp, \ref sp-flowregion.h]
- *     - SPFlowtext [\ref sp-flowtext.cpp, \ref sp-flowtext.h]
- *     - SPFlowtspan [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h]
- *     - SPGroup [\ref sp-item-group.cpp, \ref sp-item-group.h]
- *       - SPAnchor [\ref sp-anchor.cpp, \ref sp-anchor.h]
- *       - SPMarker [\ref sp-marker.cpp, \ref sp-marker.h]
- *       - SPRoot [\ref sp-root.cpp, \ref sp-root.h]
- *       - SPSymbol [\ref sp-symbol.cpp, \ref sp-symbol.h]
- *     - SPImage [\ref sp-image.cpp, \ref sp-image.h]
- *     - SPShape [\ref sp-shape.cpp, \ref sp-shape.h, \ref marker-status.cpp]
- *       - SPGenericEllipse [\ref sp-ellipse.cpp, \ref sp-ellipse.h]
- *         - SPArc
- *         - SPCircle
- *         - SPEllipse
- *       - SPLine [\ref sp-line.cpp, \ref sp-line.h]
- *       - SPOffset [\ref sp-offset.cpp, \ref sp-offset.h]
- *       - SPPath [\ref sp-path.cpp, \ref sp-path.h, \ref path-chemistry.cpp, \ref nodepath.cpp, \ref nodepath.h, \ref splivarot.cpp]
- *       - SPPolygon [\ref sp-polygon.cpp, \ref sp-polygon.h]
- *         - SPStar [\ref sp-star.cpp, \ref sp-star.h]
- *       - SPPolyLine [\ref sp-polyline.cpp, \ref sp-polyline.h]
- *       - SPRect [\ref sp-rect.cpp, \ref sp-rect.h]
- *       - SPSpiral [\ref sp-spiral.cpp, \ref sp-spiral.h]
- *     - SPText [\ref sp-text.cpp, \ref sp-text.h, \ref text-chemistry.cpp, \ref text-editing.cpp]
- *     - SPTextPath [\ref sp-tspan.cpp, \ref sp-tspan.h]
- *     - SPTSpan [\ref sp-tspan.cpp, \ref sp-tspan.h]
- *     - SPUse [\ref sp-use.cpp, \ref sp-use.h]
- *   - SPMetadata [\ref sp-metadata.cpp, \ref sp-metadata.h]
- *   - SPObjectGroup [\ref sp-object-group.cpp, \ref sp-object-group.h]
- *     - SPClipPath [\ref sp-clippath.cpp, \ref sp-clippath.h]
- *     - SPMask [\ref sp-mask.cpp, \ref sp-mask.h]
- *     - SPNamedView [\ref sp-namedview.cpp, \ref sp-namedview.h]
- *   - SPPaintServer [\ref sp-paint-server.cpp, \ref sp-paint-server.h]
- *     - SPGradient [\ref sp-gradient.cpp, \ref sp-gradient.h, \ref gradient-chemistry.cpp, \ref sp-gradient-reference.h, \ref sp-gradient-spread.h, \ref sp-gradient-units.h, \ref sp-gradient-vector.h]
- *       - SPLinearGradient
- *       - SPRadialGradient
- *     - SPPattern [\ref sp-pattern.cpp, \ref sp-pattern.h]
- *   - SPSkeleton [\ref sp-skeleton.cpp, \ref sp-skeleton.h]
- *   - SPStop [\ref sp-stop.h]
- *   - SPString [\ref sp-string.cpp, \ref sp-string.h]
- *   - SPStyleElem [\ref sp-style-elem.cpp, \ref sp-style-elem.h]
- *
- */
-/** \page Tools Tools Related Classes and Files
- *
- * SelCue [\ref selcue.cpp, \ref selcue.h, \ref rubberband.cpp]
- * Inkscape::Selection [\ref selection.cpp, \ref selection.h, \ref selection-chemistry.cpp]
- * SPSelTrans [\ref seltrans.cpp, \ref seltrans.h]
- *
- * \section Event Context Class Hierarchy
- *
- *- SPEventContext[\ref event-context.cpp, \ref event-context.h]
- * - SPArcContext [\ref arc-context.cpp, \ref arc-context.h]
- * - SPDrawContext [\ref draw-context.cpp, \ref draw-context.h]
- *   - SPPenContext [\ref pen-context.cpp, \ref pen-context.h]
- *   - SPPencilContext [\ref pencil-context.cpp, \ref pencil-context.h]
- *   - SPConnectorContext [\ref connector-context.cpp, \ref connector-context.h, \ref sp-conn-end.cpp, \ref sp-conn-end-pair.cpp]
- * - SPGradientContext [\ref gradient-context.cpp, \ref gradient-context.h, \ref gradient-drag.cpp, \ref gradient-toolbar.cpp]
- * - SPRectContext [\ref rect-context.cpp, \ref rect-context.h]
- * - SPSelectContext [\ref select-context.cpp, \ref select-context.h]
- * - SPSpiralContext [\ref spiral-context.cpp, \ref spiral-context.h]
- * - SPStarContext [\ref star-context.cpp, \ref star-context.h]
- *
- * SPNodeContext [\ref node-context.cpp, \ref node-context.h]
- *
- * SPZoomContext [\ref zoom-context.cpp, \ref zoom-context.h]
- *
- * SPDynaDrawContext [\ref dyna-draw-context.cpp, \ref dyna-draw-context.h]
- *
- * SPDropperContext [\ref dropper-context.cpp, \ref dropper-context.h]
- */
-/** \page UI User Interface Classes and Files
- *
- * - Inkscape::UI::View::View [\ref ui/view/view.cpp, \ref ui/view/view.h]
- *   - Inkscape::UI::View::Edit [\ref ui/view/edit.cpp, \ref ui/view/edit.h]
- *   - SPDesktop [\ref desktop.cpp, \ref desktop-affine.cpp, \ref desktop-events.cpp, \ref desktop-handles.cpp, \ref desktop-style.cpp, \ref desktop.h, \ref desktop-affine.h, \ref desktop-events.h, \ref desktop-handles.h, \ref desktop-style.h]
- *   - SPSVGView [\ref svg-view.cpp, \ref svg-view.h]
- *
- * SPDesktopWidget [\ref desktop-widget.h] SPSVGSPViewWidget [\ref svg-view.cpp]
- * SPDocument [\ref document.cpp, \ref document.h]
- *
- * SPDrawAnchor [\ref draw-anchor.cpp, \ref draw-anchor.h]
- * SPKnot [\ref knot.cpp, \ref knot.h, \ref knot-enums.h]
- * SPKnotHolder [\ref knotholder.cpp, \ref knotholder.h, \ref knot-holder-entity.h]
- *
- * [\ref layer-fns.cpp, \ref selection-describer.h]
- * Inkscape::MessageContext [\ref message-context.h]
- * Inkscape::MessageStack [\ref message-stack.h, \ref message.h]
- *
- * Snapper, GridSnapper, GuideSnapper [\ref snap.cpp, \ref snap.h]
- *
- * SPGuide [\ref sp-guide.cpp, \ref sp-guide.h, \ref satisfied-guide-cns.cpp, \ref sp-guide-attachment.h, \ref sp-guide-constraint.h]
- *
- * [\ref help.cpp] [\ref inkscape.cpp] [\ref inkscape-stock.cpp]
- * [\ref interface.cpp, \ref memeq.h] [\ref main.cpp, \ref winmain.cpp]
- * [\ref menus-skeleton.h, \ref preferences-skeleton.h]
- * [\ref object-ui.cpp] [\ref select-toolbar.cpp] [\ref shortcuts.cpp]
- * [\ref sp-cursor.cpp] [\ref text-edit.cpp] [\ref toolbox.cpp, \ref ui/widget/toolbox.cpp]
- * Inkscape::Verb [\ref verbs.h]
- *
- */
-/** \page XmlTree CSS/XML Tree Classes and Files
- *
- * SPStyle [\ref style.cpp, \ref style.h]
- * Media [\ref media.cpp, \ref media.h]
- * [\ref attributes.cpp, \ref attributes.h]
- *
- * - Inkscape::URIReference [\ref uri-references.cpp, \ref uri-references.h]
- *   - SPClipPathReference [\ref sp-clippath.h]
- *   - SPGradientReference [\ref sp-gradient-reference.h]
- *   - SPMarkerReference [\ref sp-marker.h]
- *   - SPMaskReference [\ref sp-mask.h]
- *   - SPUseReference [\ref sp-use-reference.h]
- *     - SPUsePath
- */
-/** \page Rendering Rendering Related Classes and Files
- *
- * SPColor [\ref color.cpp, \ref color.h, \ref color-rgba.h]
- * [\ref geom.cpp] [\ref isnan.h] [\ref mod360.cpp]
- */
-/** \page OtherServices Classes and Files From Other Services
- * [\ref inkview.cpp, \ref slideshow.cpp] [\ref sp-animation.cpp]
- *
- * Inkscape::GC
- *
- * [\ref sp-metrics.cpp, \ref sp-metrics.h]
- *
- * [\ref prefs-utils.cpp] [\ref print.cpp]
- *
- * - Inkscape::GZipBuffer [\ref streams-gzip.h]
- * - Inkscape::JarBuffer [\ref streams-jar.h]
- * - Inkscape::ZlibBuffer [\ref streams-zlib.h]
- * - Inkscape::URIHandle [\ref streams-handles.h]
- *   - Inkscape::FileHandle
- * [\ref dir-util.cpp] [\ref file.cpp]
- * Inkscape::URI [\ref uri.h, \ref extract-uri.cpp, \ref uri-references.cpp]
- * Inkscape::BadURIException [\ref bad-uri-exception.h]
- *
- * Inkscape::Whiteboard::UndoStackObserver [\ref undo-stack-observer.cpp, \ref composite-undo-stack-observer.cpp]
- * [\ref document-undo.cpp]
- *
- * {\ref dialogs/} [\ref approx-equal.h] [\ref decimal-round.h] [\ref enums.h] [\ref unit-constants.h]
- */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #include "unit-constants.h"
 
 #include "svg/svg.h"
+#include "svg/svg-color.h"
 #include "svg/stringstream.h"
 
 #include "inkscape-private.h"
@@ -325,6 +118,7 @@ enum {
     SP_ARG_EXPORT_DPI,
     SP_ARG_EXPORT_AREA,
     SP_ARG_EXPORT_AREA_DRAWING,
+    SP_ARG_EXPORT_AREA_CANVAS,
     SP_ARG_EXPORT_AREA_SNAP,
     SP_ARG_EXPORT_WIDTH,
     SP_ARG_EXPORT_HEIGHT,
@@ -336,6 +130,7 @@ enum {
     SP_ARG_EXPORT_SVG,
     SP_ARG_EXPORT_PS,
     SP_ARG_EXPORT_EPS,
+    SP_ARG_EXPORT_PDF,
     SP_ARG_EXPORT_TEXT_TO_PATH,
     SP_ARG_EXPORT_BBOX_PAGE,
     SP_ARG_EXTENSIONDIR,
@@ -355,6 +150,7 @@ int sp_main_gui(int argc, char const **argv);
 int sp_main_console(int argc, char const **argv);
 static void sp_do_export_png(SPDocument *doc);
 static void do_export_ps(SPDocument* doc, gchar const* uri, char const *mime);
+static void do_export_pdf(SPDocument* doc, gchar const* uri, char const *mime);
 static void do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id);
 
 
@@ -364,6 +160,7 @@ static gchar *sp_export_png = NULL;
 static gchar *sp_export_dpi = NULL;
 static gchar *sp_export_area = NULL;
 static gboolean sp_export_area_drawing = FALSE;
+static gboolean sp_export_area_canvas = FALSE;
 static gchar *sp_export_width = NULL;
 static gchar *sp_export_height = NULL;
 static gchar *sp_export_id = NULL;
@@ -375,6 +172,7 @@ static gboolean sp_export_id_only = FALSE;
 static gchar *sp_export_svg = NULL;
 static gchar *sp_export_ps = NULL;
 static gchar *sp_export_eps = NULL;
+static gchar *sp_export_pdf = NULL;
 static gboolean sp_export_text_to_path = FALSE;
 static gboolean sp_export_bbox_page = FALSE;
 static gboolean sp_query_x = FALSE;
@@ -439,6 +237,11 @@ struct poptOption options[] = {
      N_("Exported area is the entire drawing (not canvas)"),
      NULL},
 
+    {"export-area-canvas", 'C',
+     POPT_ARG_NONE, &sp_export_area_canvas, SP_ARG_EXPORT_AREA_CANVAS,
+     N_("Exported area is the entire canvas"),
+     NULL},
+
     {"export-area-snap", 0,
      POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP,
      N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"),
@@ -456,7 +259,7 @@ struct poptOption options[] = {
 
     {"export-id", 'i',
      POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID,
-     N_("The ID of the object to export (overrides export-area)"),
+     N_("The ID of the object to export"),
      N_("ID")},
 
     {"export-id-only", 'j',
@@ -496,6 +299,11 @@ struct poptOption options[] = {
      N_("Export document to an EPS file"),
      N_("FILENAME")},
 
+    {"export-pdf", 'A',
+     POPT_ARG_STRING, &sp_export_pdf, SP_ARG_EXPORT_PDF,
+     N_("Export document to a PDF file"),
+     N_("FILENAME")},
+
     {"export-text-to-path", 'T',
      POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH,
      N_("Convert text object to paths on export (EPS)"),
@@ -631,11 +439,15 @@ main(int argc, char **argv)
             || !strcmp(argv[i], "-i")
             || !strncmp(argv[i], "--export-area-drawing", 21)
             || !strcmp(argv[i], "-D")
+            || !strncmp(argv[i], "--export-area-canvas", 20)
+            || !strcmp(argv[i], "-C")
             || !strncmp(argv[i], "--export-id", 12)
             || !strcmp(argv[i], "-P")
             || !strncmp(argv[i], "--export-ps", 11)
             || !strcmp(argv[i], "-E")
             || !strncmp(argv[i], "--export-eps", 12)
+            || !strcmp(argv[i], "-A")
+            || !strncmp(argv[i], "--export-pdf", 12)
             || !strcmp(argv[i], "-W")
             || !strncmp(argv[i], "--query-width", 13)
             || !strcmp(argv[i], "-H")
@@ -910,6 +722,9 @@ sp_main_console(int argc, char const **argv)
             if (sp_export_eps) {
                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
             }
+            if (sp_export_pdf) {
+                do_export_pdf(doc, sp_export_pdf, "application/pdf");
+            }
             if (sp_query_width || sp_query_height) {
                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
             } else if (sp_query_x || sp_query_y) {
@@ -946,7 +761,8 @@ do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gch
 
     if (o) {
         sp_document_ensure_up_to_date (doc);
-        NR::Rect area = sp_item_bbox_desktop((SPItem *) o);
+        SPItem *item = ((SPItem *) o);
+        NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
 
         Inkscape::SVGOStringStream os;
         if (extent) {
@@ -954,7 +770,7 @@ do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gch
         } else {
             os << area.min()[axis];
         }
-        g_print ("%s\n", os.str().c_str());
+        g_print ("%s", os.str().c_str());
     }
 }
 
@@ -975,20 +791,23 @@ sp_do_export_png(SPDocument *doc)
     if (sp_export_id || sp_export_area_drawing) {
 
         SPObject *o = NULL;
-        if (sp_export_id) {
+        SPObject *o_area = NULL;
+        if (sp_export_id && sp_export_area_drawing) {
             o = doc->getObjectById(sp_export_id);
+            o_area = SP_DOCUMENT_ROOT (doc);
+        } 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_area = o;
+        } 
 
         if (o) {
             if (!SP_IS_ITEM (o)) {
                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
                 return;
             }
-            if (sp_export_area) {
-                g_warning ("Object with id=\"%s\" is being exported; --export-area is ignored.", sp_export_id);
-            }
 
             items = g_slist_prepend (items, SP_ITEM(o));
 
@@ -1028,12 +847,14 @@ sp_do_export_png(SPDocument *doc)
 
             // write object bbox to area
             sp_document_ensure_up_to_date (doc);
-            sp_item_invoke_bbox((SPItem *) o, &area, sp_item_i2r_affine((SPItem *) o), TRUE);
+            sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
         } else {
             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
             return;
         }
-    } else if (sp_export_area) {
+    }
+    
+    if (sp_export_area) {
         /* Try to parse area (given in SVG pixels) */
         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
@@ -1043,7 +864,7 @@ sp_do_export_png(SPDocument *doc)
             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
             return;
         }
-    } else {
+    } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
         /* Export the whole canvas */
         sp_document_ensure_up_to_date (doc);
         area.x0 = SP_ROOT(doc->root)->x.computed;
@@ -1147,7 +968,7 @@ sp_do_export_png(SPDocument *doc)
     g_print("Bitmap saved as: %s\n", filename);
 
     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
-        sp_export_png_file(doc, filename, area.x0, area.y0, area.x1, area.y1, width, height, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL);
+        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);
     } else {
         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
     }
@@ -1166,12 +987,6 @@ sp_do_export_png(SPDocument *doc)
 
 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
 {
-    /** \todo
-     * FIXME: I've no idea if this is the `proper' way to do this.
-     * If anyone feels qualified to say that it is, perhaps they
-     * could remove this comment.
-     */
-
     Inkscape::Extension::DB::OutputList o;
     Inkscape::Extension::db.get_output_list(o);
     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
@@ -1215,6 +1030,32 @@ static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
     }
 }
 
+/**
+ *  Perform a PDF export
+ *
+ *  \param doc Document to export.
+ *  \param uri URI to export to.
+ *  \param mime MIME type to export as.
+ */
+
+static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
+{
+    Inkscape::Extension::DB::OutputList o;
+    Inkscape::Extension::db.get_output_list(o);
+    Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
+    while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
+        i++;
+    }
+
+    if (i == o.end())
+    {
+        g_warning ("Could not find an extension to export this file.");
+        return;
+    }
+
+    (*i)->save(doc, uri);
+}
+
 #ifdef WIN32
 bool replaceArgs( int& argc, char**& argv )
 {