Code

fix leak of the arena and arenaitem
[inkscape.git] / src / splivarot.cpp
index b8c2bb2f0f891eca1c4d776a7fe4d0b9df30ab3e..b65e6c239fc55ce97f142c7e8025468ff5b24fa1 100644 (file)
@@ -33,7 +33,6 @@
 #include "text-editing.h"
 #include "sp-item-group.h"
 #include "style.h"
-#include "inkscape.h"
 #include "document.h"
 #include "message-stack.h"
 #include "selection.h"
 #include <glibmm/i18n.h>
 #include "prefs-utils.h"
 
-#include "libnr/n-art-bpath.h"
-#include "libnr/nr-path.h"
 #include "xml/repr.h"
 #include "xml/repr-sorting.h"
 #include <2geom/pathvector.h>
-#include <libnr/nr-matrix-fns.h>
-#include <libnr/nr-matrix-ops.h>
-#include <libnr/nr-matrix-translate-ops.h>
 #include <libnr/nr-scale-matrix-ops.h>
-#include <libnr/n-art-bpath-2geom.h>
 #include "helper/geom.h"
 
 #include "livarot/Path.h"
 
 bool   Ancetre(Inkscape::XML::Node *a, Inkscape::XML::Node *who);
 
-void sp_selected_path_boolop(bool_op bop, const unsigned int verb=SP_VERB_NONE, const Glib::ustring description="");
-void sp_selected_path_do_offset(bool expand, double prefOffset);
-void sp_selected_path_create_offset_object(int expand, bool updating);
+void sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb=SP_VERB_NONE, const Glib::ustring description="");
+void sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset);
+void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updating);
 
 void
-sp_selected_path_union()
+sp_selected_path_union(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_union, SP_VERB_SELECTION_UNION, _("Union"));
+    sp_selected_path_boolop(desktop, bool_op_union, SP_VERB_SELECTION_UNION, _("Union"));
 }
 
 void
-sp_selected_path_union_skip_undo()
+sp_selected_path_union_skip_undo(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_union, SP_VERB_NONE, _("Union"));
+    sp_selected_path_boolop(desktop, bool_op_union, SP_VERB_NONE, _("Union"));
 }
 
 void
-sp_selected_path_intersect()
+sp_selected_path_intersect(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_inters, SP_VERB_SELECTION_INTERSECT, _("Intersection"));
+    sp_selected_path_boolop(desktop, bool_op_inters, SP_VERB_SELECTION_INTERSECT, _("Intersection"));
 }
 
 void
-sp_selected_path_diff()
+sp_selected_path_diff(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_diff, SP_VERB_SELECTION_DIFF, _("Difference"));
+    sp_selected_path_boolop(desktop, bool_op_diff, SP_VERB_SELECTION_DIFF, _("Difference"));
 }
 
 void
-sp_selected_path_diff_skip_undo()
+sp_selected_path_diff_skip_undo(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_diff, SP_VERB_NONE, _("Difference"));
+    sp_selected_path_boolop(desktop, bool_op_diff, SP_VERB_NONE, _("Difference"));
 }
 
 void
-sp_selected_path_symdiff()
+sp_selected_path_symdiff(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_symdiff, SP_VERB_SELECTION_SYMDIFF, _("Exclusion"));
+    sp_selected_path_boolop(desktop, bool_op_symdiff, SP_VERB_SELECTION_SYMDIFF, _("Exclusion"));
 }
 void
-sp_selected_path_cut()
+sp_selected_path_cut(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_cut, SP_VERB_SELECTION_CUT, _("Division"));
+    sp_selected_path_boolop(desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division"));
 }
 void
-sp_selected_path_slice()
+sp_selected_path_slice(SPDesktop *desktop)
 {
-    sp_selected_path_boolop(bool_op_slice, SP_VERB_SELECTION_SLICE,  _("Cut path"));
+    sp_selected_path_boolop(desktop, bool_op_slice, SP_VERB_SELECTION_SLICE,  _("Cut path"));
 }
 
 
 // boolean operations
 // take the source paths from the file, do the operation, delete the originals and add the results
 void
-sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustring description)
+sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb, const Glib::ustring description)
 {
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
     Inkscape::Selection *selection = sp_desktop_selection(desktop);
     
     GSList *il = (GSList *) selection->itemList();
@@ -461,7 +452,7 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin
     // adjust style properties that depend on a possible transform in the source object in order
     // to get a correct style attribute for the new path
     SPItem* item_source = SP_ITEM(source);
-    NR::Matrix i2root = from_2geom(sp_item_i2root_affine(item_source));
+    NR::Matrix i2root(sp_item_i2root_affine(item_source));
     sp_item_adjust_stroke(item_source, NR::expansion(i2root));
     sp_item_adjust_pattern(item_source, i2root);
     sp_item_adjust_gradient(item_source, i2root);
@@ -476,7 +467,8 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin
     gchar const *style = repr_source->attribute("style");
     gchar const *mask = repr_source->attribute("mask");
     gchar const *clip_path = repr_source->attribute("clip-path");
-
+    gchar *title = source->title();
+    gchar *desc = source->desc();
     // remove source paths
     selection->clear();
     for (GSList *l = il; l != NULL; l = l->next) {
@@ -493,7 +485,7 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin
 
     // premultiply by the inverse of parent's repr
     SPItem *parent_item = SP_ITEM(sp_desktop_document(desktop)->getObjectByRepr(parent));
-    NR::Matrix local = from_2geom(sp_item_i2doc_affine(parent_item));
+    NR::Matrix local (sp_item_i2doc_affine(parent_item));
     gchar *transform = sp_svg_transform_write(local.inverse());
 
     // now that we have the result, add it on the canvas
@@ -585,13 +577,21 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin
 
         repr->setAttribute("id", id);
         parent->appendChild(repr);
-        repr->setPosition(pos > 0 ? pos : 0);
+        if (title) {
+               sp_desktop_document(desktop)->getObjectByRepr(repr)->setTitle(title);
+        }            
+        if (desc) {
+               sp_desktop_document(desktop)->getObjectByRepr(repr)->setDesc(desc);
+        }
+               repr->setPosition(pos > 0 ? pos : 0);
 
         selection->add(repr);
         Inkscape::GC::release(repr);
     }
 
     g_free(transform);
+    if (title) g_free(title);
+    if (desc) g_free(desc);
 
     if (verb != SP_VERB_NONE) {
         sp_document_done(sp_desktop_document(desktop), verb, description);
@@ -607,7 +607,7 @@ void sp_selected_path_outline_add_marker( SPObject *marker_object, Geom::Matrix
     SPMarker* marker = SP_MARKER (marker_object);
     SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (marker_object));
 
-    NR::Matrix tr(from_2geom(marker_transform));
+    NR::Matrix tr(marker_transform);
 
     if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
         tr = stroke_scale * tr;
@@ -625,10 +625,8 @@ void sp_selected_path_outline_add_marker( SPObject *marker_object, Geom::Matrix
 }
 
 void
-sp_selected_path_outline()
+sp_selected_path_outline(SPDesktop *desktop)
 {
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
     Inkscape::Selection *selection = sp_desktop_selection(desktop);
 
     if (selection->isEmpty()) {
@@ -808,7 +806,11 @@ sp_selected_path_outline()
         Inkscape::XML::Node *parent = SP_OBJECT_REPR(item)->parent();
         // remember id
         char const *id = SP_OBJECT_REPR(item)->attribute("id");
-
+        // remember title
+        gchar *title = item->title();
+        // remember description
+        gchar *desc = item->desc();
+        
         if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether
 
             SPDocument * doc = sp_desktop_document(desktop);
@@ -840,10 +842,17 @@ sp_selected_path_outline()
                 g_repr->setPosition(pos > 0 ? pos : 0);
 
                 g_repr->appendChild(repr);
+                // restore title, description, id, transform
                 repr->setAttribute("id", id);
                 SPItem *newitem = (SPItem *) doc->getObjectByRepr(repr);
                 sp_item_write_transform(newitem, repr, transform);
-
+                if (title) {
+                       newitem->setTitle(title);
+                }
+                if (desc) {
+                       newitem->setDesc(desc);
+                }
+                
                 SPShape *shape = SP_SHAPE(item);
 
                 Geom::PathVector const & pathv = curve->get_pathvector();
@@ -855,7 +864,8 @@ sp_selected_path_outline()
                                                              g_repr, xml_doc, doc );
                     }
 
-                    if ( SPObject *marker_obj = shape->marker[SP_MARKER_LOC_MID] ) {
+                    SPObject *midmarker_obj = shape->marker[SP_MARKER_LOC_MID];
+                    if ( midmarker_obj && (path_it->size_default() > 1) ) {
                         Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
                         Geom::Path::const_iterator curve_it2 = ++(path_it->begin());  // outgoing curve
                         while (curve_it2 != path_it->end_default())
@@ -865,7 +875,7 @@ sp_selected_path_outline()
                              * there should be a midpoint marker between last segment and closing straight line segment
                              */
                             Geom::Matrix const m (sp_shape_marker_get_transform(*curve_it1, *curve_it2));
-                            sp_selected_path_outline_add_marker( marker_obj, m,
+                            sp_selected_path_outline_add_marker( midmarker_obj, m,
                                                                  NR::scale(i_style->stroke_width.computed), transform,
                                                                  g_repr, xml_doc, doc );
 
@@ -875,7 +885,15 @@ sp_selected_path_outline()
                     }
 
                     if ( SPObject *marker_obj = shape->marker[SP_MARKER_LOC_END] ) {
-                        Geom::Matrix const m (sp_shape_marker_get_transform_at_end(path_it->back_default()));
+                        /* Get reference to last curve in the path.
+                         * For moveto-only path, this returns the "closing line segment". */
+                        unsigned int index = path_it->size_default();
+                        if (index > 0) {
+                            index--;
+                        }
+                        Geom::Curve const &lastcurve = (*path_it)[index];
+
+                        Geom::Matrix const m = sp_shape_marker_get_transform_at_end(lastcurve);
                         sp_selected_path_outline_add_marker( marker_obj, m,
                                                              NR::scale(i_style->stroke_width.computed), transform,
                                                              g_repr, xml_doc, doc );
@@ -895,11 +913,18 @@ sp_selected_path_outline()
                 // move to the saved position
                 repr->setPosition(pos > 0 ? pos : 0);
 
+                // restore title, description, id, transform
                 repr->setAttribute("id", id);
 
                 SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
                 sp_item_write_transform(newitem, repr, transform);
-
+                if (title) {
+                       newitem->setTitle(title);
+                }
+                if (desc) {
+                       newitem->setDesc(desc);
+                }
+                
                 selection->add(repr);
 
             }
@@ -911,6 +936,8 @@ sp_selected_path_outline()
             SP_OBJECT(item)->deleteObject(false);
 
         }
+        if (title) g_free(title);
+        if (desc) g_free(desc);
 
         delete res;
         delete orig;
@@ -928,78 +955,75 @@ sp_selected_path_outline()
 
 
 void
-sp_selected_path_offset()
+sp_selected_path_offset(SPDesktop *desktop)
 {
     double prefOffset = prefs_get_double_attribute("options.defaultoffsetwidth", "value", 1.0);
 
-    sp_selected_path_do_offset(true, prefOffset);
+    sp_selected_path_do_offset(desktop, true, prefOffset);
 }
 void
-sp_selected_path_inset()
+sp_selected_path_inset(SPDesktop *desktop)
 {
     double prefOffset = prefs_get_double_attribute("options.defaultoffsetwidth", "value", 1.0);
 
-    sp_selected_path_do_offset(false, prefOffset);
+    sp_selected_path_do_offset(desktop, false, prefOffset);
 }
 
 void
-sp_selected_path_offset_screen(double pixels)
+sp_selected_path_offset_screen(SPDesktop *desktop, double pixels)
 {
-    sp_selected_path_do_offset(true,  pixels / SP_ACTIVE_DESKTOP->current_zoom());
+    sp_selected_path_do_offset(desktop, true,  pixels / desktop->current_zoom());
 }
 
 void
-sp_selected_path_inset_screen(double pixels)
+sp_selected_path_inset_screen(SPDesktop *desktop, double pixels)
 {
-    sp_selected_path_do_offset(false,  pixels / SP_ACTIVE_DESKTOP->current_zoom());
+    sp_selected_path_do_offset(desktop, false,  pixels / desktop->current_zoom());
 }
 
 
-void sp_selected_path_create_offset_object_zero()
+void sp_selected_path_create_offset_object_zero(SPDesktop *desktop)
 {
-    sp_selected_path_create_offset_object(0, false);
+    sp_selected_path_create_offset_object(desktop, 0, false);
 }
 
-void sp_selected_path_create_offset()
+void sp_selected_path_create_offset(SPDesktop *desktop)
 {
-    sp_selected_path_create_offset_object(1, false);
+    sp_selected_path_create_offset_object(desktop, 1, false);
 }
-void sp_selected_path_create_inset()
+void sp_selected_path_create_inset(SPDesktop *desktop)
 {
-    sp_selected_path_create_offset_object(-1, false);
+    sp_selected_path_create_offset_object(desktop, -1, false);
 }
 
-void sp_selected_path_create_updating_offset_object_zero()
+void sp_selected_path_create_updating_offset_object_zero(SPDesktop *desktop)
 {
-    sp_selected_path_create_offset_object(0, true);
+    sp_selected_path_create_offset_object(desktop, 0, true);
 }
 
-void sp_selected_path_create_updating_offset()
+void sp_selected_path_create_updating_offset(SPDesktop *desktop)
 {
-    sp_selected_path_create_offset_object(1, true);
+    sp_selected_path_create_offset_object(desktop, 1, true);
 }
-void sp_selected_path_create_updating_inset()
+void sp_selected_path_create_updating_inset(SPDesktop *desktop)
 {
-    sp_selected_path_create_offset_object(-1, true);
+    sp_selected_path_create_offset_object(desktop, -1, true);
 }
 
 void
-sp_selected_path_create_offset_object(int expand, bool updating)
+sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updating)
 {
     Inkscape::Selection *selection;
     Inkscape::XML::Node *repr;
     SPItem *item;
     SPCurve *curve;
     gchar *style, *str;
-    SPDesktop *desktop;
     float o_width, o_miter;
     JoinType o_join;
     ButtType o_butt;
 
     curve = NULL;
 
-    desktop = SP_ACTIVE_DESKTOP;
-
     selection = sp_desktop_selection(desktop);
 
     item = selection->singleItem();
@@ -1215,10 +1239,8 @@ sp_selected_path_create_offset_object(int expand, bool updating)
 
 
 void
-sp_selected_path_do_offset(bool expand, double prefOffset)
+sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset)
 {
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
     Inkscape::Selection *selection = sp_desktop_selection(desktop);
 
     if (selection->isEmpty()) {
@@ -1522,7 +1544,11 @@ sp_selected_path_simplify_item(SPDesktop *desktop,
     char const *id = SP_OBJECT_REPR(item)->attribute("id");
     // remember path effect
     char const *patheffect = SP_OBJECT_REPR(item)->attribute("inkscape:path-effect");
-
+    // remember title
+    gchar *title = item->title();
+    // remember description
+    gchar *desc = item->desc();
+    
     //If a group was selected, to not change the selection list
     if (modifySelection)
         selection->remove(item);
@@ -1577,7 +1603,17 @@ sp_selected_path_simplify_item(SPDesktop *desktop,
 
     // restore path effect
     repr->setAttribute("inkscape:path-effect", patheffect);
-
+    
+    // restore title & description
+    if (title) {
+       newitem->setTitle(title);
+        g_free(title);
+    }
+    if (desc) {
+       newitem->setDesc(desc);
+        g_free(desc);
+    }
+    
     //If we are not in a selected group
     if (modifySelection)
         selection->add(repr);
@@ -1610,7 +1646,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
 
   bool didSomething = false;
 
-  NR::Maybe<NR::Rect> selectionBbox = selection->bounds();
+  boost::optional<NR::Rect> selectionBbox = selection->bounds();
   if (!selectionBbox) {
     return false;
   }
@@ -1631,7 +1667,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
           continue;
 
       if (simplifyIndividualPaths) {
-          NR::Maybe<NR::Rect> itemBbox = item->getBounds(from_2geom(sp_item_i2d_affine(item)));
+          boost::optional<NR::Rect> itemBbox = item->getBounds(sp_item_i2d_affine(item));
           if (itemBbox) {
               simplifySize      = L2(itemBbox->dimensions());
           } else {
@@ -1660,11 +1696,9 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
 }
 
 void
-sp_selected_path_simplify_selection(float threshold, bool justCoalesce,
-                       float angleLimit, bool breakableAngles)
+sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool justCoalesce,
+                                    float angleLimit, bool breakableAngles)
 {
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
     Inkscape::Selection *selection = sp_desktop_selection(desktop);
 
     if (selection->isEmpty()) {
@@ -1695,7 +1729,7 @@ static double previousTime      = 0.0;
 static gdouble simplifyMultiply = 1.0;
 
 void
-sp_selected_path_simplify(void)
+sp_selected_path_simplify(SPDesktop *desktop)
 {
     gdouble simplifyThreshold =
         prefs_get_double_attribute("options.simplifythreshold", "value", 0.003);
@@ -1726,8 +1760,8 @@ sp_selected_path_simplify(void)
     //g_print("%g\n", simplify_threshold);
 
     //Make the actual call
-    sp_selected_path_simplify_selection(simplifyThreshold,
-                      simplifyJustCoalesce, 0.0, false);
+    sp_selected_path_simplify_selection(desktop, simplifyThreshold,
+                                        simplifyJustCoalesce, 0.0, false);
 }
 
 
@@ -1748,79 +1782,55 @@ Path *
 Path_for_item(SPItem *item, bool doTransformation, bool transformFull)
 {
     SPCurve *curve = curve_for_item(item);
+
     if (curve == NULL)
         return NULL;
-
-    Geom::PathVector pathv = pathvector_for_curve(item, curve, doTransformation, transformFull);
-
-    Path *dest = new Path;
-    dest->LoadPathVector(pathv);
-
+    
+    Geom::PathVector *pathv = pathvector_for_curve(item, curve, doTransformation, transformFull, Geom::identity(), Geom::identity());
     curve->unref();
     
+    Path *dest = new Path;
+    dest->LoadPathVector(*pathv);    
+    delete pathv;
+    
     return dest;
 }
 
-/* 
- * This function always returns a new NArtBpath, the caller must g_free the returned path!
-*/
-NArtBpath *
-bpath_for_curve(SPItem *item, SPCurve *curve, bool doTransformation, bool transformFull, NR::Matrix extraPreAffine, NR::Matrix extraPostAffine)
-{
-    if (curve == NULL)
-        return NULL;
-
-    NArtBpath *bpath = BPath_from_2GeomPath(curve->get_pathvector());
-    if (bpath == NULL) {
-        return NULL;
-    }
-
-    NArtBpath *new_bpath; // we will get a duplicate which has to be freed at some point!
-    if (doTransformation) {
-        if (transformFull) {
-            new_bpath = nr_artpath_affine(bpath, extraPreAffine * from_2geom(sp_item_i2doc_affine(item)) * extraPostAffine);
-        } else {
-            new_bpath = nr_artpath_affine(bpath, extraPreAffine * item->transform * extraPostAffine);
-        }
-    } else {
-        new_bpath = nr_artpath_affine(bpath, extraPreAffine * NR::identity() * extraPostAffine);
-    }
-
-    g_free(bpath);
-    return new_bpath;
-}
-
 /* 
  * NOTE: Returns empty pathvector if curve == NULL
  * TODO: see if calling this method can be optimized. All the pathvector copying might be slow.
  */
-Geom::PathVector
-pathvector_for_curve(SPItem *item, SPCurve *curve, bool doTransformation, bool transformFull)
+Geom::PathVector*
+pathvector_for_curve(SPItem *item, SPCurve *curve, bool doTransformation, bool transformFull, Geom::Matrix extraPreAffine, Geom::Matrix extraPostAffine)
 {
     if (curve == NULL)
-        return Geom::PathVector();
+        return NULL;
 
+    Geom::PathVector *dest = new Geom::PathVector;    
+    *dest = curve->get_pathvector(); // Make a copy; must be freed by the caller!
+    
     if (doTransformation) {
         if (transformFull) {
-            return (curve->get_pathvector()) * sp_item_i2doc_affine(item);
+            *dest *= extraPreAffine * sp_item_i2doc_affine(item) * extraPostAffine;
         } else {
-            return (curve->get_pathvector()) * to_2geom(item->transform);
+            *dest *= extraPreAffine * (Geom::Matrix)item->transform * extraPostAffine;
         }
     } else {
-        return curve->get_pathvector();
+        *dest *= extraPreAffine * extraPostAffine;
     }
+    
+    return dest;
 }
 
 SPCurve* curve_for_item(SPItem *item)
 {
-    if (!item) {
-       return NULL;
-    }
-
+    if (!item) 
+        return NULL;
+    
     SPCurve *curve = NULL;
     if (SP_IS_SHAPE(item)) {
         if (SP_IS_PATH(item)) {
-               curve = sp_path_get_curve_for_edit(SP_PATH(item));
+            curve = sp_path_get_curve_for_edit(SP_PATH(item));
         } else {
             curve = sp_shape_get_curve(SP_SHAPE(item));
         }
@@ -1831,70 +1841,13 @@ SPCurve* curve_for_item(SPItem *item)
     }
     else if (SP_IS_IMAGE(item))
     {
-       curve = sp_image_get_curve(SP_IMAGE(item));
+    curve = sp_image_get_curve(SP_IMAGE(item));
     }
     
     return curve; // do not forget to unref the curve at some point!
 }
 
-Path *bpath_to_Path(NArtBpath const *bpath) {
-    Path *dest = new Path;
-    dest->SetBackData(false);
-    {
-        int   i;
-        bool  closed = false;
-        float lastX  = 0.0;
-        float lastY  = 0.0;
-
-        for (i = 0; bpath[i].code != NR_END; i++) {
-            switch (bpath[i].code) {
-                case NR_LINETO:
-                    lastX = bpath[i].x3;
-                    lastY = bpath[i].y3;
-                    {
-                        NR::Point tmp(lastX, lastY);
-                        dest->LineTo(tmp);
-                    }
-                    break;
-
-                case NR_CURVETO:
-                {
-                    NR::Point tmp, tms, tme;
-                    tmp[0]=bpath[i].x3;
-                    tmp[1]=bpath[i].y3;
-                    tms[0]=3 * (bpath[i].x1 - lastX);
-                    tms[1]=3 * (bpath[i].y1 - lastY);
-                    tme[0]=3 * (bpath[i].x3 - bpath[i].x2);
-                    tme[1]=3 * (bpath[i].y3 - bpath[i].y2);
-                    dest->CubicTo(tmp,tms,tme);
-                }
-                lastX = bpath[i].x3;
-                lastY = bpath[i].y3;
-                break;
-
-                case NR_MOVETO_OPEN:
-                case NR_MOVETO:
-                    if (closed)
-                        dest->Close();
-                    closed = (bpath[i].code == NR_MOVETO);
-                    lastX = bpath[i].x3;
-                    lastY = bpath[i].y3;
-                    {
-                        NR::Point  tmp(lastX, lastY);
-                        dest->MoveTo(tmp);
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-        if (closed)
-            dest->Close();
-    }
-    return dest;
-}
-
-NR::Maybe<Path::cut_position> get_nearest_position_on_Path(Path *path, NR::Point p, unsigned seg)
+boost::optional<Path::cut_position> get_nearest_position_on_Path(Path *path, NR::Point p, unsigned seg)
 {
     //get nearest position on path
     Path::cut_position pos = path->PointToCurvilignPosition(p, seg);