Code

trivial: live_effects/**: svn propset svn:eol-style native *.h *.cpp.
authorpjrm <pjrm@users.sourceforge.net>
Thu, 11 Oct 2007 14:30:52 +0000 (14:30 +0000)
committerpjrm <pjrm@users.sourceforge.net>
Thu, 11 Oct 2007 14:30:52 +0000 (14:30 +0000)
31 files changed:
src/live_effects/effect.cpp
src/live_effects/effect.h
src/live_effects/lpe-curvestitch.cpp
src/live_effects/lpe-curvestitch.h
src/live_effects/lpe-gears.cpp
src/live_effects/lpe-gears.h
src/live_effects/lpe-skeletalstrokes.cpp
src/live_effects/lpe-skeletalstrokes.h
src/live_effects/lpe-skeleton.cpp
src/live_effects/lpe-skeleton.h
src/live_effects/lpe-slant.cpp
src/live_effects/lpe-slant.h
src/live_effects/lpe-test-doEffect-stack.cpp
src/live_effects/lpe-test-doEffect-stack.h
src/live_effects/lpeobject-reference.cpp
src/live_effects/lpeobject-reference.h
src/live_effects/lpeobject.cpp
src/live_effects/lpeobject.h
src/live_effects/n-art-bpath-2geom.cpp
src/live_effects/n-art-bpath-2geom.h
src/live_effects/parameter/bool.cpp
src/live_effects/parameter/bool.h
src/live_effects/parameter/enum.h
src/live_effects/parameter/parameter.cpp
src/live_effects/parameter/parameter.h
src/live_effects/parameter/path.cpp
src/live_effects/parameter/path.h
src/live_effects/parameter/point.cpp
src/live_effects/parameter/point.h
src/live_effects/parameter/random.cpp
src/live_effects/parameter/random.h

index 0773363dddfe4daa825a83a590cf305efefbc9a8..1c0f5318f4d9fa3e55179ab38b2ed4c01517c90e 100644 (file)
-#define INKSCAPE_LIVEPATHEFFECT_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "display/display-forward.h"\r
-#include "xml/node-event-vector.h"\r
-#include "sp-object.h"\r
-#include "attributes.h"\r
-#include "message-stack.h"\r
-#include "desktop.h"\r
-#include "inkscape.h"\r
-#include "document.h"\r
-#include <glibmm/i18n.h>\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/lpeobject.h"\r
-#include "live_effects/parameter/parameter.h"\r
-#include <glibmm/ustring.h>\r
-#include "live_effects/n-art-bpath-2geom.h"\r
-#include "display/curve.h"\r
-#include <2geom/sbasis-to-bezier.h>\r
-#include <gtkmm.h>\r
-\r
-#include <exception>\r
-\r
-// include effects:\r
-#include "live_effects/lpe-skeletalstrokes.h"\r
-#include "live_effects/lpe-slant.h"\r
-#include "live_effects/lpe-test-doEffect-stack.h"\r
-#include "live_effects/lpe-gears.h"\r
-#include "live_effects/lpe-curvestitch.h"\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-const Util::EnumData<EffectType> LPETypeData[INVALID_LPE] = {\r
-    // {constant defined in effect.h, N_("name of your effect"), "name of your effect in SVG"}\r
-    {SKELETAL_STROKES,      N_("Path along path"),      "skeletal"},\r
-#ifdef LPE_ENABLE_TEST_EFFECTS\r
-    {SLANT,                 N_("Slant"),                 "slant"},\r
-    {DOEFFECTSTACK_TEST,    N_("doEffect stack test"),   "doeffectstacktest"},\r
-#endif\r
-    {GEARS,                 N_("Gears"),                 "gears"},\r
-    {CURVE_STITCH,          N_("Curve stitching"),       "curvestitching"},\r
-};\r
-const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, INVALID_LPE);\r
-\r
-Effect*\r
-Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)\r
-{\r
-    Effect* neweffect = NULL;\r
-    switch (lpenr) {\r
-        case SKELETAL_STROKES:\r
-            neweffect = (Effect*) new LPESkeletalStrokes(lpeobj);\r
-            break;\r
-#ifdef LPE_ENABLE_TEST_EFFECTS\r
-            case SLANT:\r
-            neweffect = (Effect*) new LPESlant(lpeobj);\r
-            break;\r
-        case DOEFFECTSTACK_TEST:\r
-            neweffect = (Effect*) new LPEdoEffectStackTest(lpeobj);\r
-            break;\r
-#endif\r
-        case GEARS:\r
-            neweffect = (Effect*) new LPEGears(lpeobj);\r
-            break;\r
-        case CURVE_STITCH:\r
-            neweffect = (Effect*) new LPECurveStitch(lpeobj);\r
-            break;\r
-        default:\r
-            g_warning("LivePathEffect::Effect::New   called with invalid patheffect type (%d)", lpenr);\r
-            neweffect = NULL;\r
-            break;\r
-    }\r
-\r
-    if (neweffect) {\r
-        neweffect->readallParameters(SP_OBJECT_REPR(lpeobj));\r
-    }\r
-\r
-    return neweffect;\r
-}\r
-\r
-Effect::Effect(LivePathEffectObject *lpeobject)\r
-{\r
-    vbox = NULL;\r
-    tooltips = NULL;\r
-    lpeobj = lpeobject;\r
-}\r
-\r
-Effect::~Effect()\r
-{\r
-    if (tooltips) {\r
-        delete tooltips;\r
-    }\r
-}\r
-\r
-Glib::ustring \r
-Effect::getName()\r
-{\r
-    if (lpeobj->effecttype_set && lpeobj->effecttype < INVALID_LPE)\r
-        return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) );\r
-    else\r
-        return Glib::ustring( _("No effect") );\r
-}\r
-\r
-/*\r
- *  Here be the doEffect function chain:\r
- */\r
-void\r
-Effect::doEffect (SPCurve * curve)\r
-{\r
-    NArtBpath *new_bpath = doEffect(SP_CURVE_BPATH(curve));\r
-\r
-    if (new_bpath && new_bpath != SP_CURVE_BPATH(curve)) {        // FIXME, add function to SPCurve to change bpath? or a copy function?\r
-        if (curve->_bpath) {\r
-            g_free(curve->_bpath); //delete old bpath\r
-        }\r
-        curve->_bpath = new_bpath;\r
-    }\r
-}\r
-\r
-NArtBpath *\r
-Effect::doEffect (NArtBpath * path_in)\r
-{\r
-    try {\r
-        std::vector<Geom::Path> orig_pathv = BPath_to_2GeomPath(path_in);\r
-\r
-        std::vector<Geom::Path> result_pathv = doEffect(orig_pathv);\r
-\r
-        NArtBpath *new_bpath = BPath_from_2GeomPath(result_pathv);\r
-\r
-        return new_bpath;\r
-    }\r
-    catch (std::exception e) {\r
-        g_warning("An exception occurred during execution of an LPE - %s", e.what());\r
-        SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE,\r
-            _("An exception occurred during execution of a Path Effect.") );\r
-\r
-        NArtBpath *path_out;\r
-\r
-        unsigned ret = 0;\r
-        while ( path_in[ret].code != NR_END ) {\r
-            ++ret;\r
-        }\r
-        unsigned len = ++ret;\r
-\r
-        path_out = g_new(NArtBpath, len);\r
-        memcpy(path_out, path_in, len * sizeof(NArtBpath));\r
-        return path_out;\r
-    }\r
-}\r
-\r
-std::vector<Geom::Path>\r
-Effect::doEffect (std::vector<Geom::Path> & path_in)\r
-{\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in;\r
-\r
-    for (unsigned int i=0; i < path_in.size(); i++) {\r
-        pwd2_in.concat( path_in[i].toPwSb() );\r
-    }\r
-\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect(pwd2_in);\r
-\r
-    std::vector<Geom::Path> path_out = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);\r
-\r
-    return path_out;\r
-}\r
-\r
-Geom::Piecewise<Geom::D2<Geom::SBasis> >\r
-Effect::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)\r
-{\r
-    g_warning("Effect has no doEffect implementation");\r
-    return pwd2_in;\r
-}\r
-\r
-void\r
-Effect::readallParameters(Inkscape::XML::Node * repr)\r
-{\r
-    param_map_type::iterator it = param_map.begin();\r
-    while (it != param_map.end()) {\r
-        const gchar * key = (*it).first.c_str();\r
-        const gchar * value = repr->attribute(key);\r
-        if(value) {\r
-            setParameter(repr, key, NULL, value);\r
-        }\r
-        it++;\r
-    }\r
-}\r
-\r
-void\r
-Effect::setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar * old_value, const gchar * new_value)\r
-{\r
-    Glib::ustring stringkey(key);\r
-\r
-    param_map_type::iterator it = param_map.find(stringkey);\r
-    if (it != param_map.end()) {\r
-        if (new_value) {\r
-            bool accepted = it->second->param_readSVGValue(new_value);\r
-            if (!accepted) { \r
-                g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key);\r
-                // change was not accepted, so change it back.\r
-                // think: can this backfire and create infinite loop when started with unacceptable old_value?\r
-                // repr->setAttribute(key, old_value);\r
-            }\r
-        } else {\r
-            // set default value\r
-            it->second->param_set_default();\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-Effect::registerParameter(Parameter * param)\r
-{\r
-    param_map[param->param_key] = param; // inserts or updates\r
-}\r
-\r
-Gtk::Widget *\r
-Effect::getWidget()\r
-{\r
-    if (!vbox) {\r
-        vbox = Gtk::manage( new Gtk::VBox() ); // use manage here, because after deletion of Effect object, others might still be pointing to this widget.\r
-        //if (!tooltips)\r
-            tooltips = new Gtk::Tooltips();\r
-\r
-        vbox->set_border_width(5);\r
-\r
-        param_map_type::iterator it = param_map.begin();\r
-        while (it != param_map.end()) {\r
-            Parameter * param = it->second;\r
-            Gtk::Widget * widg = param->param_getWidget();\r
-            Glib::ustring * tip = param->param_getTooltip();\r
-            if (widg) {\r
-               vbox->pack_start(*widg, true, true, 2);\r
-                if (tip != NULL) {\r
-                    tooltips->set_tip(*widg, *tip);\r
-                }\r
-            }\r
-\r
-            it++;\r
-        }\r
-    }\r
-\r
-    return dynamic_cast<Gtk::Widget *>(vbox);\r
-}\r
-\r
-\r
-Inkscape::XML::Node * \r
-Effect::getRepr()\r
-{\r
-    return SP_OBJECT_REPR(lpeobj);\r
-}\r
-\r
-SPDocument * \r
-Effect::getSPDoc()\r
-{\r
-    if (SP_OBJECT_DOCUMENT(lpeobj) == NULL) g_message("Effect::getSPDoc() returns NULL");\r
-    return SP_OBJECT_DOCUMENT(lpeobj);\r
-}\r
-\r
-\r
-} /* namespace LivePathEffect */\r
-\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "display/display-forward.h"
+#include "xml/node-event-vector.h"
+#include "sp-object.h"
+#include "attributes.h"
+#include "message-stack.h"
+#include "desktop.h"
+#include "inkscape.h"
+#include "document.h"
+#include <glibmm/i18n.h>
+
+#include "live_effects/effect.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/parameter/parameter.h"
+#include <glibmm/ustring.h>
+#include "live_effects/n-art-bpath-2geom.h"
+#include "display/curve.h"
+#include <2geom/sbasis-to-bezier.h>
+#include <gtkmm.h>
+
+#include <exception>
+
+// include effects:
+#include "live_effects/lpe-skeletalstrokes.h"
+#include "live_effects/lpe-slant.h"
+#include "live_effects/lpe-test-doEffect-stack.h"
+#include "live_effects/lpe-gears.h"
+#include "live_effects/lpe-curvestitch.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+const Util::EnumData<EffectType> LPETypeData[INVALID_LPE] = {
+    // {constant defined in effect.h, N_("name of your effect"), "name of your effect in SVG"}
+    {SKELETAL_STROKES,      N_("Path along path"),      "skeletal"},
+#ifdef LPE_ENABLE_TEST_EFFECTS
+    {SLANT,                 N_("Slant"),                 "slant"},
+    {DOEFFECTSTACK_TEST,    N_("doEffect stack test"),   "doeffectstacktest"},
+#endif
+    {GEARS,                 N_("Gears"),                 "gears"},
+    {CURVE_STITCH,          N_("Curve stitching"),       "curvestitching"},
+};
+const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, INVALID_LPE);
+
+Effect*
+Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
+{
+    Effect* neweffect = NULL;
+    switch (lpenr) {
+        case SKELETAL_STROKES:
+            neweffect = (Effect*) new LPESkeletalStrokes(lpeobj);
+            break;
+#ifdef LPE_ENABLE_TEST_EFFECTS
+            case SLANT:
+            neweffect = (Effect*) new LPESlant(lpeobj);
+            break;
+        case DOEFFECTSTACK_TEST:
+            neweffect = (Effect*) new LPEdoEffectStackTest(lpeobj);
+            break;
+#endif
+        case GEARS:
+            neweffect = (Effect*) new LPEGears(lpeobj);
+            break;
+        case CURVE_STITCH:
+            neweffect = (Effect*) new LPECurveStitch(lpeobj);
+            break;
+        default:
+            g_warning("LivePathEffect::Effect::New   called with invalid patheffect type (%d)", lpenr);
+            neweffect = NULL;
+            break;
+    }
+
+    if (neweffect) {
+        neweffect->readallParameters(SP_OBJECT_REPR(lpeobj));
+    }
+
+    return neweffect;
+}
+
+Effect::Effect(LivePathEffectObject *lpeobject)
+{
+    vbox = NULL;
+    tooltips = NULL;
+    lpeobj = lpeobject;
+}
+
+Effect::~Effect()
+{
+    if (tooltips) {
+        delete tooltips;
+    }
+}
+
+Glib::ustring 
+Effect::getName()
+{
+    if (lpeobj->effecttype_set && lpeobj->effecttype < INVALID_LPE)
+        return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) );
+    else
+        return Glib::ustring( _("No effect") );
+}
+
+/*
+ *  Here be the doEffect function chain:
+ */
+void
+Effect::doEffect (SPCurve * curve)
+{
+    NArtBpath *new_bpath = doEffect(SP_CURVE_BPATH(curve));
+
+    if (new_bpath && new_bpath != SP_CURVE_BPATH(curve)) {        // FIXME, add function to SPCurve to change bpath? or a copy function?
+        if (curve->_bpath) {
+            g_free(curve->_bpath); //delete old bpath
+        }
+        curve->_bpath = new_bpath;
+    }
+}
+
+NArtBpath *
+Effect::doEffect (NArtBpath * path_in)
+{
+    try {
+        std::vector<Geom::Path> orig_pathv = BPath_to_2GeomPath(path_in);
+
+        std::vector<Geom::Path> result_pathv = doEffect(orig_pathv);
+
+        NArtBpath *new_bpath = BPath_from_2GeomPath(result_pathv);
+
+        return new_bpath;
+    }
+    catch (std::exception e) {
+        g_warning("An exception occurred during execution of an LPE - %s", e.what());
+        SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE,
+            _("An exception occurred during execution of a Path Effect.") );
+
+        NArtBpath *path_out;
+
+        unsigned ret = 0;
+        while ( path_in[ret].code != NR_END ) {
+            ++ret;
+        }
+        unsigned len = ++ret;
+
+        path_out = g_new(NArtBpath, len);
+        memcpy(path_out, path_in, len * sizeof(NArtBpath));
+        return path_out;
+    }
+}
+
+std::vector<Geom::Path>
+Effect::doEffect (std::vector<Geom::Path> & path_in)
+{
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in;
+
+    for (unsigned int i=0; i < path_in.size(); i++) {
+        pwd2_in.concat( path_in[i].toPwSb() );
+    }
+
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect(pwd2_in);
+
+    std::vector<Geom::Path> path_out = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);
+
+    return path_out;
+}
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+Effect::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)
+{
+    g_warning("Effect has no doEffect implementation");
+    return pwd2_in;
+}
+
+void
+Effect::readallParameters(Inkscape::XML::Node * repr)
+{
+    param_map_type::iterator it = param_map.begin();
+    while (it != param_map.end()) {
+        const gchar * key = (*it).first.c_str();
+        const gchar * value = repr->attribute(key);
+        if(value) {
+            setParameter(repr, key, NULL, value);
+        }
+        it++;
+    }
+}
+
+void
+Effect::setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar * old_value, const gchar * new_value)
+{
+    Glib::ustring stringkey(key);
+
+    param_map_type::iterator it = param_map.find(stringkey);
+    if (it != param_map.end()) {
+        if (new_value) {
+            bool accepted = it->second->param_readSVGValue(new_value);
+            if (!accepted) { 
+                g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key);
+                // change was not accepted, so change it back.
+                // think: can this backfire and create infinite loop when started with unacceptable old_value?
+                // repr->setAttribute(key, old_value);
+            }
+        } else {
+            // set default value
+            it->second->param_set_default();
+        }
+    }
+}
+
+void
+Effect::registerParameter(Parameter * param)
+{
+    param_map[param->param_key] = param; // inserts or updates
+}
+
+Gtk::Widget *
+Effect::getWidget()
+{
+    if (!vbox) {
+        vbox = Gtk::manage( new Gtk::VBox() ); // use manage here, because after deletion of Effect object, others might still be pointing to this widget.
+        //if (!tooltips)
+            tooltips = new Gtk::Tooltips();
+
+        vbox->set_border_width(5);
+
+        param_map_type::iterator it = param_map.begin();
+        while (it != param_map.end()) {
+            Parameter * param = it->second;
+            Gtk::Widget * widg = param->param_getWidget();
+            Glib::ustring * tip = param->param_getTooltip();
+            if (widg) {
+               vbox->pack_start(*widg, true, true, 2);
+                if (tip != NULL) {
+                    tooltips->set_tip(*widg, *tip);
+                }
+            }
+
+            it++;
+        }
+    }
+
+    return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
+
+Inkscape::XML::Node * 
+Effect::getRepr()
+{
+    return SP_OBJECT_REPR(lpeobj);
+}
+
+SPDocument * 
+Effect::getSPDoc()
+{
+    if (SP_OBJECT_DOCUMENT(lpeobj) == NULL) g_message("Effect::getSPDoc() returns NULL");
+    return SP_OBJECT_DOCUMENT(lpeobj);
+}
+
+
+} /* namespace LivePathEffect */
+
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index f3c415269dc52890710372f57d83b6af2f903322..5169ff22f5d6345239138627e044244fecb1917c 100644 (file)
-#ifndef INKSCAPE_LIVEPATHEFFECT_H\r
-#define INKSCAPE_LIVEPATHEFFECT_H\r
-\r
-/*\r
- * Inkscape::LivePathEffect\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-\r
-#include "display/display-forward.h"\r
-#include <map>\r
-#include <glibmm/ustring.h>\r
-#include <2geom/path.h>\r
-#include "ui/widget/registry.h"\r
-#include "util/enums.h"\r
-\r
-#define  LPE_CONVERSION_TOLERANCE 0.01    // FIXME: find good solution for this.\r
-\r
-//#define LPE_ENABLE_TEST_EFFECTS\r
-\r
-struct SPShape;\r
-struct SPDocument;\r
-class NArtBpath;\r
-struct LivePathEffectObject;\r
-\r
-namespace Gtk {\r
-    class Widget;\r
-    class VBox;\r
-    class Tooltips;\r
-}\r
-\r
-namespace Inkscape {\r
-\r
-namespace XML {\r
-    class Node;\r
-}\r
-\r
-namespace LivePathEffect {\r
-\r
-enum EffectType {\r
-    SKELETAL_STROKES = 0,\r
-#ifdef LPE_ENABLE_TEST_EFFECTS\r
-    SLANT,\r
-    DOEFFECTSTACK_TEST,\r
-#endif\r
-    GEARS,\r
-    CURVE_STITCH,\r
-    INVALID_LPE // This must be last\r
-};\r
-\r
-extern const Util::EnumData<EffectType> LPETypeData[INVALID_LPE];\r
-extern const Util::EnumDataConverter<EffectType> LPETypeConverter;\r
-\r
-class Parameter;\r
-\r
-class Effect {\r
-public:\r
-    virtual ~Effect();\r
-\r
-    Glib::ustring getName();\r
-\r
-    virtual void doEffect (SPCurve * curve);\r
-\r
-    static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj);\r
-\r
-    virtual Gtk::Widget * getWidget();\r
-\r
-    Inkscape::XML::Node * getRepr();\r
-    SPDocument * getSPDoc();\r
-\r
-    void readallParameters(Inkscape::XML::Node * repr);\r
-    void setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar * old_value, const gchar * new_value);\r
-\r
-protected:\r
-    Effect(LivePathEffectObject *lpeobject);\r
-\r
-    // provide a set of doEffect functions so the developer has a choice \r
-    // of what kind of input/output parameters he desires.\r
-    // the order in which they appear is the order in which they are \r
-    // called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling\r
-    // doEffect(std::vector<Geom::Path> )\r
-    virtual NArtBpath *\r
-            doEffect (NArtBpath * path_in);\r
-    virtual std::vector<Geom::Path> \r
-            doEffect (std::vector<Geom::Path> & path_in);\r
-    virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > \r
-            doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);\r
-\r
-    void registerParameter(Parameter * param);\r
-\r
-    typedef std::map<Glib::ustring, Parameter *> param_map_type;\r
-    param_map_type param_map;\r
-\r
-    Inkscape::UI::Widget::Registry wr; \r
-    Gtk::VBox * vbox;\r
-    Gtk::Tooltips * tooltips;\r
-\r
-    LivePathEffectObject *lpeobj;\r
-\r
-private:\r
-    Effect(const Effect&);\r
-    Effect& operator=(const Effect&);\r
-};\r
-\r
-\r
-} //namespace LivePathEffect\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_H
+#define INKSCAPE_LIVEPATHEFFECT_H
+
+/*
+ * Inkscape::LivePathEffect
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+
+#include "display/display-forward.h"
+#include <map>
+#include <glibmm/ustring.h>
+#include <2geom/path.h>
+#include "ui/widget/registry.h"
+#include "util/enums.h"
+
+#define  LPE_CONVERSION_TOLERANCE 0.01    // FIXME: find good solution for this.
+
+//#define LPE_ENABLE_TEST_EFFECTS
+
+struct SPShape;
+struct SPDocument;
+class NArtBpath;
+struct LivePathEffectObject;
+
+namespace Gtk {
+    class Widget;
+    class VBox;
+    class Tooltips;
+}
+
+namespace Inkscape {
+
+namespace XML {
+    class Node;
+}
+
+namespace LivePathEffect {
+
+enum EffectType {
+    SKELETAL_STROKES = 0,
+#ifdef LPE_ENABLE_TEST_EFFECTS
+    SLANT,
+    DOEFFECTSTACK_TEST,
+#endif
+    GEARS,
+    CURVE_STITCH,
+    INVALID_LPE // This must be last
+};
+
+extern const Util::EnumData<EffectType> LPETypeData[INVALID_LPE];
+extern const Util::EnumDataConverter<EffectType> LPETypeConverter;
+
+class Parameter;
+
+class Effect {
+public:
+    virtual ~Effect();
+
+    Glib::ustring getName();
+
+    virtual void doEffect (SPCurve * curve);
+
+    static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj);
+
+    virtual Gtk::Widget * getWidget();
+
+    Inkscape::XML::Node * getRepr();
+    SPDocument * getSPDoc();
+
+    void readallParameters(Inkscape::XML::Node * repr);
+    void setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar * old_value, const gchar * new_value);
+
+protected:
+    Effect(LivePathEffectObject *lpeobject);
+
+    // provide a set of doEffect functions so the developer has a choice 
+    // of what kind of input/output parameters he desires.
+    // the order in which they appear is the order in which they are 
+    // called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling
+    // doEffect(std::vector<Geom::Path> )
+    virtual NArtBpath *
+            doEffect (NArtBpath * path_in);
+    virtual std::vector<Geom::Path> 
+            doEffect (std::vector<Geom::Path> & path_in);
+    virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > 
+            doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
+
+    void registerParameter(Parameter * param);
+
+    typedef std::map<Glib::ustring, Parameter *> param_map_type;
+    param_map_type param_map;
+
+    Inkscape::UI::Widget::Registry wr; 
+    Gtk::VBox * vbox;
+    Gtk::Tooltips * tooltips;
+
+    LivePathEffectObject *lpeobj;
+
+private:
+    Effect(const Effect&);
+    Effect& operator=(const Effect&);
+};
+
+
+} //namespace LivePathEffect
+} //namespace Inkscape
+
+#endif
index 7368fd55b7498438a1ee03d3bbb8e119ac097b09..c39277727fc2c4b339ce30b007d4462513458545 100644 (file)
-#define INKSCAPE_LPE_EXPRESSION_CPP\r
-/** \file\r
- * SVG <skeleton> implementation, used as an example for a base starting class\r
- * when implementing new LivePathEffects.\r
- *\r
- */\r
-/*\r
- * Authors:\r
- *   Johan Engelen\r
-*\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/lpe-curvestitch.h"\r
-#include "display/curve.h"\r
-#include <libnr/n-art-bpath.h>\r
-\r
-#include <2geom/path.h>\r
-#include <2geom/piecewise.h>\r
-#include <2geom/sbasis.h>\r
-#include <2geom/sbasis-geometric.h>\r
-#include <2geom/bezier-to-sbasis.h>\r
-#include <2geom/sbasis-to-bezier.h>\r
-#include <2geom/d2.h>\r
-#include <2geom/matrix.h>\r
-\r
-\r
-#include "ui/widget/scalar.h"\r
-#include "libnr/nr-values.h"\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-using namespace Geom;\r
-\r
-LPECurveStitch::LPECurveStitch(LivePathEffectObject *lpeobject) :\r
-    Effect(lpeobject),\r
-    strokepath(_("Stroke path"), _("The path that will be stroked, whatever, think of good text here."), "strokepath", &wr, this, "M0,0 L1,0"),\r
-    nrofpaths(_("Nr of paths"), _("The number of paths that will be generated."), "count", &wr, this, 5),\r
-    startpoint_variation(_("Startpoint variation"), _("..."), "startpoint_variation", &wr, this, 0),\r
-    endpoint_variation(_("Endpoint variation"), _("..."), "endpoint_variation", &wr, this, 0),\r
-    prop_scale(_("Scale width"), _("Scaling of the width of the stroke path"), "prop_scale", &wr, this, 1),\r
-    scale_y_rel(_("Scale width relative"), _("Scale the width of the stroke path relative to its length"), "scale_y_rel", &wr, this, false)\r
-{\r
-    registerParameter( dynamic_cast<Parameter *>(&nrofpaths) );\r
-    registerParameter( dynamic_cast<Parameter *>(&startpoint_variation) );\r
-    registerParameter( dynamic_cast<Parameter *>(&endpoint_variation) );\r
-    registerParameter( dynamic_cast<Parameter *>(&strokepath) );\r
-    registerParameter( dynamic_cast<Parameter *>(&prop_scale) );\r
-    registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );\r
-\r
-    nrofpaths.param_make_integer();\r
-    nrofpaths.param_set_range(2, NR_HUGE);\r
-\r
-    prop_scale.param_set_digits(3);\r
-    prop_scale.param_set_increments(0.01, 0.10);\r
-}\r
-\r
-LPECurveStitch::~LPECurveStitch()\r
-{\r
-\r
-}\r
-\r
-std::vector<Geom::Path>\r
-LPECurveStitch::doEffect (std::vector<Geom::Path> & path_in)\r
-{\r
-    if (path_in.size() >= 2) {\r
-        startpoint_variation.resetRandomizer();\r
-        endpoint_variation.resetRandomizer();\r
-\r
-        D2<Piecewise<SBasis> > stroke = make_cuts_independant(strokepath);\r
-        Interval bndsStroke = bounds_exact(stroke[0]);\r
-        gdouble scaling = bndsStroke.max() - bndsStroke.min();\r
-        Interval bndsStrokeY = bounds_exact(stroke[1]);\r
-        Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2);\r
-\r
-        std::vector<Geom::Path> path_out (nrofpaths);\r
-\r
-        // do this for all permutations if there are more than 2 paths? realllly cool!\r
-        Piecewise<D2<SBasis> > A = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[0].toPwSb()),2,.1);\r
-        Piecewise<D2<SBasis> > B = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[1].toPwSb()),2,.1);\r
-        Interval bndsA = A.domain();\r
-        Interval bndsB = B.domain();\r
-        gdouble incrementA = (bndsA.max()-bndsA.min()) / (nrofpaths-1);\r
-        gdouble incrementB = (bndsB.max()-bndsB.min()) / (nrofpaths-1);\r
-        gdouble tA = bndsA.min();\r
-        gdouble tB = bndsB.min();\r
-        for (int i = 0; i < nrofpaths; i++) {\r
-            Point start = A(tA);\r
-            Point end = B(tB);\r
-            if (startpoint_variation.get_value() != 0)\r
-                start = start + startpoint_variation * (end - start);\r
-            if (endpoint_variation.get_value() != 0)\r
-                end = end + endpoint_variation * (end - start);\r
-    \r
-            gdouble scaling_y = 1.0;\r
-            if (scale_y_rel.get_value()) {\r
-                scaling_y = (L2(end-start)/scaling)*prop_scale;\r
-            } else {\r
-                scaling_y = prop_scale;\r
-            }\r
-\r
-            Matrix transform;\r
-            transform.setXAxis( (end-start) / scaling );\r
-            transform.setYAxis( rot90(unit_vector(end-start)) * scaling_y);\r
-            transform.setTranslation( start );\r
-            Piecewise<D2<SBasis> > pwd2_out = (strokepath-stroke_origin) * transform;\r
-            // add stuff to one big pw<d2<sbasis> > and then outside the loop convert to path?\r
-            std::vector<Path> result = Geom::path_from_piecewise(pwd2_out, LPE_CONVERSION_TOLERANCE);\r
-            path_out[i] = result[0];\r
-            tA += incrementA;\r
-            tB += incrementB;\r
-        }\r
-\r
-        return path_out;\r
-    } else {\r
-        return path_in;\r
-    }\r
-}\r
-\r
-} //namespace LivePathEffect\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LPE_EXPRESSION_CPP
+/** \file
+ * SVG <skeleton> implementation, used as an example for a base starting class
+ * when implementing new LivePathEffects.
+ *
+ */
+/*
+ * Authors:
+ *   Johan Engelen
+*
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-curvestitch.h"
+#include "display/curve.h"
+#include <libnr/n-art-bpath.h>
+
+#include <2geom/path.h>
+#include <2geom/piecewise.h>
+#include <2geom/sbasis.h>
+#include <2geom/sbasis-geometric.h>
+#include <2geom/bezier-to-sbasis.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
+#include <2geom/matrix.h>
+
+
+#include "ui/widget/scalar.h"
+#include "libnr/nr-values.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+using namespace Geom;
+
+LPECurveStitch::LPECurveStitch(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    strokepath(_("Stroke path"), _("The path that will be stroked, whatever, think of good text here."), "strokepath", &wr, this, "M0,0 L1,0"),
+    nrofpaths(_("Nr of paths"), _("The number of paths that will be generated."), "count", &wr, this, 5),
+    startpoint_variation(_("Startpoint variation"), _("..."), "startpoint_variation", &wr, this, 0),
+    endpoint_variation(_("Endpoint variation"), _("..."), "endpoint_variation", &wr, this, 0),
+    prop_scale(_("Scale width"), _("Scaling of the width of the stroke path"), "prop_scale", &wr, this, 1),
+    scale_y_rel(_("Scale width relative"), _("Scale the width of the stroke path relative to its length"), "scale_y_rel", &wr, this, false)
+{
+    registerParameter( dynamic_cast<Parameter *>(&nrofpaths) );
+    registerParameter( dynamic_cast<Parameter *>(&startpoint_variation) );
+    registerParameter( dynamic_cast<Parameter *>(&endpoint_variation) );
+    registerParameter( dynamic_cast<Parameter *>(&strokepath) );
+    registerParameter( dynamic_cast<Parameter *>(&prop_scale) );
+    registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );
+
+    nrofpaths.param_make_integer();
+    nrofpaths.param_set_range(2, NR_HUGE);
+
+    prop_scale.param_set_digits(3);
+    prop_scale.param_set_increments(0.01, 0.10);
+}
+
+LPECurveStitch::~LPECurveStitch()
+{
+
+}
+
+std::vector<Geom::Path>
+LPECurveStitch::doEffect (std::vector<Geom::Path> & path_in)
+{
+    if (path_in.size() >= 2) {
+        startpoint_variation.resetRandomizer();
+        endpoint_variation.resetRandomizer();
+
+        D2<Piecewise<SBasis> > stroke = make_cuts_independant(strokepath);
+        Interval bndsStroke = bounds_exact(stroke[0]);
+        gdouble scaling = bndsStroke.max() - bndsStroke.min();
+        Interval bndsStrokeY = bounds_exact(stroke[1]);
+        Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2);
+
+        std::vector<Geom::Path> path_out (nrofpaths);
+
+        // do this for all permutations if there are more than 2 paths? realllly cool!
+        Piecewise<D2<SBasis> > A = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[0].toPwSb()),2,.1);
+        Piecewise<D2<SBasis> > B = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[1].toPwSb()),2,.1);
+        Interval bndsA = A.domain();
+        Interval bndsB = B.domain();
+        gdouble incrementA = (bndsA.max()-bndsA.min()) / (nrofpaths-1);
+        gdouble incrementB = (bndsB.max()-bndsB.min()) / (nrofpaths-1);
+        gdouble tA = bndsA.min();
+        gdouble tB = bndsB.min();
+        for (int i = 0; i < nrofpaths; i++) {
+            Point start = A(tA);
+            Point end = B(tB);
+            if (startpoint_variation.get_value() != 0)
+                start = start + startpoint_variation * (end - start);
+            if (endpoint_variation.get_value() != 0)
+                end = end + endpoint_variation * (end - start);
+    
+            gdouble scaling_y = 1.0;
+            if (scale_y_rel.get_value()) {
+                scaling_y = (L2(end-start)/scaling)*prop_scale;
+            } else {
+                scaling_y = prop_scale;
+            }
+
+            Matrix transform;
+            transform.setXAxis( (end-start) / scaling );
+            transform.setYAxis( rot90(unit_vector(end-start)) * scaling_y);
+            transform.setTranslation( start );
+            Piecewise<D2<SBasis> > pwd2_out = (strokepath-stroke_origin) * transform;
+            // add stuff to one big pw<d2<sbasis> > and then outside the loop convert to path?
+            std::vector<Path> result = Geom::path_from_piecewise(pwd2_out, LPE_CONVERSION_TOLERANCE);
+            path_out[i] = result[0];
+            tA += incrementA;
+            tB += incrementB;
+        }
+
+        return path_out;
+    } else {
+        return path_in;
+    }
+}
+
+} //namespace LivePathEffect
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 25ddb7719a9c9ad110c5be5703ec2790060f8793..fd41f6849c2643293dc0bf1971303c6085ae3802 100644 (file)
@@ -1,48 +1,48 @@
-#ifndef INKSCAPE_LPE_EXPRESSION_H\r
-#define INKSCAPE_LPE_EXPRESSION_H\r
-\r
-/** \file\r
- * Implementation of an effect similar to Expression, see lpe-expression.cpp\r
- */\r
-\r
-/*\r
- * Authors:\r
- *   Johan Engelen\r
-*\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/parameter/path.h"\r
-#include "live_effects/parameter/parameter.h"\r
-#include "live_effects/parameter/bool.h"\r
-#include "live_effects/parameter/random.h"\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-class LPECurveStitch : public Effect {\r
-public:\r
-    LPECurveStitch(LivePathEffectObject *lpeobject);\r
-    ~LPECurveStitch();\r
-\r
-    std::vector<Geom::Path> doEffect (std::vector<Geom::Path> & path_in);\r
-\r
-private:\r
-    PathParam strokepath;\r
-    ScalarParam nrofpaths;\r
-    RandomParam startpoint_variation;\r
-    RandomParam endpoint_variation;\r
-    ScalarParam prop_scale;\r
-    BoolParam scale_y_rel;\r
-\r
-    LPECurveStitch(const LPECurveStitch&);\r
-    LPECurveStitch& operator=(const LPECurveStitch&);\r
-};\r
-\r
-} //namespace LivePathEffect\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LPE_EXPRESSION_H
+#define INKSCAPE_LPE_EXPRESSION_H
+
+/** \file
+ * Implementation of an effect similar to Expression, see lpe-expression.cpp
+ */
+
+/*
+ * Authors:
+ *   Johan Engelen
+*
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/path.h"
+#include "live_effects/parameter/parameter.h"
+#include "live_effects/parameter/bool.h"
+#include "live_effects/parameter/random.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPECurveStitch : public Effect {
+public:
+    LPECurveStitch(LivePathEffectObject *lpeobject);
+    ~LPECurveStitch();
+
+    std::vector<Geom::Path> doEffect (std::vector<Geom::Path> & path_in);
+
+private:
+    PathParam strokepath;
+    ScalarParam nrofpaths;
+    RandomParam startpoint_variation;
+    RandomParam endpoint_variation;
+    ScalarParam prop_scale;
+    BoolParam scale_y_rel;
+
+    LPECurveStitch(const LPECurveStitch&);
+    LPECurveStitch& operator=(const LPECurveStitch&);
+};
+
+} //namespace LivePathEffect
+} //namespace Inkscape
+
+#endif
index 03e19f31cac47b48d428ac832f74f9f960b9f21e..2176f3ba7881fea3c9e56b7de591a8a8bf1bcf86 100644 (file)
-#define INKSCAPE_LPE_DOEFFECT_STACK_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/lpe-gears.h"\r
-\r
-#include <vector>\r
-#include <2geom/d2.h>\r
-#include <2geom/sbasis.h>\r
-#include <2geom/bezier-to-sbasis.h>\r
-#include <2geom/path.h>\r
-\r
-using std::vector;\r
-using namespace Geom;\r
-\r
-class Gear {\r
-public:\r
-    // pitch circles touch on two properly meshed gears\r
-    // all measurements are taken from the pitch circle\r
-    double pitch_diameter() {return (_number_of_teeth * _module) / M_PI;}\r
-    double pitch_radius() {return pitch_diameter() / 2.0;}\r
-    void pitch_radius(double R) {_module = (2 * M_PI * R) / _number_of_teeth;}\r
-    \r
-    // base circle serves as the basis for the involute toothe profile\r
-    double base_diameter() {return pitch_diameter() * cos(_pressure_angle);}\r
-    double base_radius() {return base_diameter() / 2.0;}\r
-    \r
-    // diametrical pitch\r
-    double diametrical_pitch() {return _number_of_teeth / pitch_diameter();}\r
-    \r
-    // height of the tooth above the pitch circle\r
-    double addendum() {return 1.0 / diametrical_pitch();}\r
-    // depth of the tooth below the pitch circle\r
-    double dedendum() {return addendum() + _clearance;}\r
-    \r
-    // root circle specifies the bottom of the fillet between teeth\r
-    double root_radius() {return pitch_radius() - dedendum();}\r
-    double root_diameter() {return root_radius() * 2.0;}\r
-    \r
-    // outer circle is the outside diameter of the gear\r
-    double outer_radius() {return pitch_radius() + addendum();}\r
-    double outer_diameter() {return outer_radius() * 2.0;}\r
-    \r
-    // angle covered by the tooth on the pitch circle\r
-    double tooth_thickness_angle() {return M_PI / _number_of_teeth;}\r
-    \r
-    Geom::Point centre() {return _centre;}\r
-    void centre(Geom::Point c) {_centre = c;}\r
-    \r
-    double angle() {return _angle;}\r
-    void angle(double a) {_angle = a;}\r
-    \r
-    int number_of_teeth() {return _number_of_teeth;}\r
-    \r
-    Geom::Path path();\r
-    Gear spawn(Geom::Point p);\r
-    \r
-    Gear(int n, double m, double phi) {\r
-        _number_of_teeth = n;\r
-        _module = m;\r
-        _pressure_angle = phi;\r
-        _clearance = 0.0;\r
-        _angle = 0.0;\r
-        _centre = Geom::Point(0.0,0.0);\r
-    }\r
-private:\r
-    int _number_of_teeth;\r
-    double _pressure_angle;\r
-    double _module;\r
-    double _clearance;\r
-    double _angle;\r
-    Geom::Point _centre;\r
-    D2<SBasis> _involute(double start, double stop) {\r
-        D2<SBasis> B;\r
-        D2<SBasis> I;\r
-        Linear bo = Linear(start,stop);\r
-        \r
-        B[0] = cos(bo,2);\r
-        B[1] = sin(bo,2);\r
-        \r
-        I = B - Linear(0,1) * derivative(B);\r
-        I = I*base_radius() + _centre;\r
-        return I;\r
-    }\r
-    D2<SBasis> _arc(double start, double stop, double R) {\r
-        D2<SBasis> B;\r
-        Linear bo = Linear(start,stop);\r
-        \r
-        B[0] = cos(bo,2);\r
-        B[1] = sin(bo,2);\r
-        \r
-        B = B*R + _centre;\r
-        return B;\r
-    }\r
-    // angle of the base circle used to create the involute to a certain radius\r
-    double involute_swath_angle(double R) {\r
-        if (R <= base_radius()) return 0.0;\r
-        return sqrt(R*R - base_radius()*base_radius())/base_radius();\r
-    }\r
-\r
-    // angle of the base circle between the origin of the involute and the intersection on another radius\r
-    double involute_intersect_angle(double R) {\r
-        if (R <= base_radius()) return 0.0;\r
-        return (sqrt(R*R - base_radius()*base_radius())/base_radius()) - acos(base_radius()/R);\r
-    }\r
-};\r
-\r
-void makeContinuous(D2<SBasis> &a, Point const b) {\r
-    for(unsigned d=0;d<2;d++)\r
-        a[d][0][0] = b[d];\r
-}\r
-\r
-Geom::Path Gear::path() {\r
-    Geom::Path pb;\r
-    \r
-    // angle covered by a full tooth and fillet\r
-    double tooth_rotation = 2.0 * tooth_thickness_angle();\r
-    // angle covered by an involute\r
-    double involute_advance = involute_intersect_angle(outer_radius()) - involute_intersect_angle(root_radius());\r
-    // angle covered by the tooth tip\r
-    double tip_advance = tooth_thickness_angle() - (2 * (involute_intersect_angle(outer_radius()) - involute_intersect_angle(pitch_radius())));\r
-    // angle covered by the toothe root\r
-    double root_advance = (tooth_rotation - tip_advance) - (2.0 * involute_advance);\r
-    // begin drawing the involute at t if the root circle is larger than the base circle\r
-    double involute_t = involute_swath_angle(root_radius())/involute_swath_angle(outer_radius());\r
-    \r
-    //rewind angle to start drawing from the leading edge of the tooth\r
-    double first_tooth_angle = _angle - ((0.5 * tip_advance) + involute_advance);\r
-    \r
-    Geom::Point prev;\r
-    for (int i=0; i < _number_of_teeth; i++)\r
-    {\r
-        double cursor = first_tooth_angle + (i * tooth_rotation);\r
-\r
-        D2<SBasis> leading_I = compose(_involute(cursor, cursor + involute_swath_angle(outer_radius())), Linear(involute_t,1));\r
-        if(i != 0) makeContinuous(leading_I, prev);\r
-        pb.append(SBasisCurve(leading_I));\r
-        cursor += involute_advance;\r
-        prev = leading_I.at1();\r
-\r
-        D2<SBasis> tip = _arc(cursor, cursor+tip_advance, outer_radius());\r
-        makeContinuous(tip, prev);\r
-        pb.append(SBasisCurve(tip));\r
-        cursor += tip_advance;\r
-        prev = tip.at1();\r
-\r
-        cursor += involute_advance;\r
-        D2<SBasis> trailing_I = compose(_involute(cursor, cursor - involute_swath_angle(outer_radius())), Linear(1,involute_t));\r
-        makeContinuous(trailing_I, prev);\r
-        pb.append(SBasisCurve(trailing_I));\r
-        prev = trailing_I.at1();\r
-\r
-        if (base_radius() > root_radius()) {\r
-            Geom::Point leading_start = trailing_I.at1();\r
-            Geom::Point leading_end = (root_radius() * unit_vector(leading_start - _centre)) + _centre;\r
-            prev = leading_end;\r
-            pb.appendNew<LineSegment>(leading_end);\r
-        }\r
-        \r
-        D2<SBasis> root = _arc(cursor, cursor+root_advance, root_radius());\r
-        makeContinuous(root, prev);\r
-        pb.append(SBasisCurve(root));\r
-        cursor += root_advance;\r
-        prev = root.at1();\r
-        \r
-        if (base_radius() > root_radius()) {\r
-            Geom::Point trailing_start = root.at1();\r
-            Geom::Point trailing_end = (base_radius() * unit_vector(trailing_start - _centre)) + _centre;\r
-            pb.appendNew<LineSegment>(trailing_end);\r
-            prev = trailing_end;\r
-        }\r
-    }\r
-    \r
-    return pb;\r
-}\r
-\r
-Gear Gear::spawn(Geom::Point p) {\r
-    double radius = Geom::distance(this->centre(), p) - this->pitch_radius();\r
-    int N  = (int) floor( (radius / this->pitch_radius()) * this->number_of_teeth() );\r
-\r
-    Gear gear(N, _module, _pressure_angle);\r
-    gear.centre(p);\r
-\r
-    double a = atan2(p - this->centre());\r
-    double new_angle = 0.0;\r
-    if (gear.number_of_teeth() % 2 == 0)\r
-        new_angle -= gear.tooth_thickness_angle();\r
-    new_angle -= (_angle) * (pitch_radius() / gear.pitch_radius());\r
-    new_angle += (a) * (pitch_radius() / gear.pitch_radius());\r
-    gear.angle(new_angle + a);\r
-    return gear;\r
-}\r
-\r
-\r
-\r
-// #################################################################\r
-\r
-\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-\r
-LPEGears::LPEGears(LivePathEffectObject *lpeobject) :\r
-    Effect(lpeobject),\r
-    teeth(_("Teeth"), _("The number of teeth"), "teeth", &wr, this, 10),\r
-    phi(_("Phi"), _("???"), "phi", &wr, this, 5)\r
-{\r
-    registerParameter( dynamic_cast<Parameter *>(&teeth) );\r
-    registerParameter( dynamic_cast<Parameter *>(&phi) );\r
-}\r
-\r
-LPEGears::~LPEGears()\r
-{\r
-\r
-}\r
-\r
-std::vector<Geom::Path>\r
-LPEGears::doEffect (std::vector<Geom::Path> & path_in)\r
-{\r
-    std::vector<Geom::Path> path_out;\r
-    Geom::Path gearpath = path_in[0];\r
-\r
-    Geom::Path::iterator it(gearpath.begin());\r
-    if ( it == gearpath.end() ) return path_out;\r
-\r
-    Gear * gear = new Gear(teeth, 200.0, phi * M_PI / 180);\r
-    Geom::Point gear_centre = (*it).finalPoint();\r
-    gear->centre(gear_centre);\r
-    gear->angle(atan2((*it).initialPoint() - gear_centre));\r
-\r
-    it++; if ( it == gearpath.end() ) return path_out;\r
-    gear->pitch_radius(Geom::distance(gear_centre, (*it).finalPoint()));\r
-\r
-    path_out.push_back( gear->path());\r
-\r
-    for (it++ ; it != gearpath.end() ; it++) {\r
-        // iterate through Geom::Curve in path_in\r
-        Gear* gearnew = new Gear(gear->spawn( (*it).finalPoint() ));\r
-        path_out.push_back( gearnew->path() );\r
-        delete gear;\r
-        gear = gearnew;\r
-    }\r
-    delete gear;\r
-\r
-    return path_out;\r
-}\r
-\r
-\r
-} // namespace LivePathEffect\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LPE_DOEFFECT_STACK_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-gears.h"
+
+#include <vector>
+#include <2geom/d2.h>
+#include <2geom/sbasis.h>
+#include <2geom/bezier-to-sbasis.h>
+#include <2geom/path.h>
+
+using std::vector;
+using namespace Geom;
+
+class Gear {
+public:
+    // pitch circles touch on two properly meshed gears
+    // all measurements are taken from the pitch circle
+    double pitch_diameter() {return (_number_of_teeth * _module) / M_PI;}
+    double pitch_radius() {return pitch_diameter() / 2.0;}
+    void pitch_radius(double R) {_module = (2 * M_PI * R) / _number_of_teeth;}
+    
+    // base circle serves as the basis for the involute toothe profile
+    double base_diameter() {return pitch_diameter() * cos(_pressure_angle);}
+    double base_radius() {return base_diameter() / 2.0;}
+    
+    // diametrical pitch
+    double diametrical_pitch() {return _number_of_teeth / pitch_diameter();}
+    
+    // height of the tooth above the pitch circle
+    double addendum() {return 1.0 / diametrical_pitch();}
+    // depth of the tooth below the pitch circle
+    double dedendum() {return addendum() + _clearance;}
+    
+    // root circle specifies the bottom of the fillet between teeth
+    double root_radius() {return pitch_radius() - dedendum();}
+    double root_diameter() {return root_radius() * 2.0;}
+    
+    // outer circle is the outside diameter of the gear
+    double outer_radius() {return pitch_radius() + addendum();}
+    double outer_diameter() {return outer_radius() * 2.0;}
+    
+    // angle covered by the tooth on the pitch circle
+    double tooth_thickness_angle() {return M_PI / _number_of_teeth;}
+    
+    Geom::Point centre() {return _centre;}
+    void centre(Geom::Point c) {_centre = c;}
+    
+    double angle() {return _angle;}
+    void angle(double a) {_angle = a;}
+    
+    int number_of_teeth() {return _number_of_teeth;}
+    
+    Geom::Path path();
+    Gear spawn(Geom::Point p);
+    
+    Gear(int n, double m, double phi) {
+        _number_of_teeth = n;
+        _module = m;
+        _pressure_angle = phi;
+        _clearance = 0.0;
+        _angle = 0.0;
+        _centre = Geom::Point(0.0,0.0);
+    }
+private:
+    int _number_of_teeth;
+    double _pressure_angle;
+    double _module;
+    double _clearance;
+    double _angle;
+    Geom::Point _centre;
+    D2<SBasis> _involute(double start, double stop) {
+        D2<SBasis> B;
+        D2<SBasis> I;
+        Linear bo = Linear(start,stop);
+        
+        B[0] = cos(bo,2);
+        B[1] = sin(bo,2);
+        
+        I = B - Linear(0,1) * derivative(B);
+        I = I*base_radius() + _centre;
+        return I;
+    }
+    D2<SBasis> _arc(double start, double stop, double R) {
+        D2<SBasis> B;
+        Linear bo = Linear(start,stop);
+        
+        B[0] = cos(bo,2);
+        B[1] = sin(bo,2);
+        
+        B = B*R + _centre;
+        return B;
+    }
+    // angle of the base circle used to create the involute to a certain radius
+    double involute_swath_angle(double R) {
+        if (R <= base_radius()) return 0.0;
+        return sqrt(R*R - base_radius()*base_radius())/base_radius();
+    }
+
+    // angle of the base circle between the origin of the involute and the intersection on another radius
+    double involute_intersect_angle(double R) {
+        if (R <= base_radius()) return 0.0;
+        return (sqrt(R*R - base_radius()*base_radius())/base_radius()) - acos(base_radius()/R);
+    }
+};
+
+void makeContinuous(D2<SBasis> &a, Point const b) {
+    for(unsigned d=0;d<2;d++)
+        a[d][0][0] = b[d];
+}
+
+Geom::Path Gear::path() {
+    Geom::Path pb;
+    
+    // angle covered by a full tooth and fillet
+    double tooth_rotation = 2.0 * tooth_thickness_angle();
+    // angle covered by an involute
+    double involute_advance = involute_intersect_angle(outer_radius()) - involute_intersect_angle(root_radius());
+    // angle covered by the tooth tip
+    double tip_advance = tooth_thickness_angle() - (2 * (involute_intersect_angle(outer_radius()) - involute_intersect_angle(pitch_radius())));
+    // angle covered by the toothe root
+    double root_advance = (tooth_rotation - tip_advance) - (2.0 * involute_advance);
+    // begin drawing the involute at t if the root circle is larger than the base circle
+    double involute_t = involute_swath_angle(root_radius())/involute_swath_angle(outer_radius());
+    
+    //rewind angle to start drawing from the leading edge of the tooth
+    double first_tooth_angle = _angle - ((0.5 * tip_advance) + involute_advance);
+    
+    Geom::Point prev;
+    for (int i=0; i < _number_of_teeth; i++)
+    {
+        double cursor = first_tooth_angle + (i * tooth_rotation);
+
+        D2<SBasis> leading_I = compose(_involute(cursor, cursor + involute_swath_angle(outer_radius())), Linear(involute_t,1));
+        if(i != 0) makeContinuous(leading_I, prev);
+        pb.append(SBasisCurve(leading_I));
+        cursor += involute_advance;
+        prev = leading_I.at1();
+
+        D2<SBasis> tip = _arc(cursor, cursor+tip_advance, outer_radius());
+        makeContinuous(tip, prev);
+        pb.append(SBasisCurve(tip));
+        cursor += tip_advance;
+        prev = tip.at1();
+
+        cursor += involute_advance;
+        D2<SBasis> trailing_I = compose(_involute(cursor, cursor - involute_swath_angle(outer_radius())), Linear(1,involute_t));
+        makeContinuous(trailing_I, prev);
+        pb.append(SBasisCurve(trailing_I));
+        prev = trailing_I.at1();
+
+        if (base_radius() > root_radius()) {
+            Geom::Point leading_start = trailing_I.at1();
+            Geom::Point leading_end = (root_radius() * unit_vector(leading_start - _centre)) + _centre;
+            prev = leading_end;
+            pb.appendNew<LineSegment>(leading_end);
+        }
+        
+        D2<SBasis> root = _arc(cursor, cursor+root_advance, root_radius());
+        makeContinuous(root, prev);
+        pb.append(SBasisCurve(root));
+        cursor += root_advance;
+        prev = root.at1();
+        
+        if (base_radius() > root_radius()) {
+            Geom::Point trailing_start = root.at1();
+            Geom::Point trailing_end = (base_radius() * unit_vector(trailing_start - _centre)) + _centre;
+            pb.appendNew<LineSegment>(trailing_end);
+            prev = trailing_end;
+        }
+    }
+    
+    return pb;
+}
+
+Gear Gear::spawn(Geom::Point p) {
+    double radius = Geom::distance(this->centre(), p) - this->pitch_radius();
+    int N  = (int) floor( (radius / this->pitch_radius()) * this->number_of_teeth() );
+
+    Gear gear(N, _module, _pressure_angle);
+    gear.centre(p);
+
+    double a = atan2(p - this->centre());
+    double new_angle = 0.0;
+    if (gear.number_of_teeth() % 2 == 0)
+        new_angle -= gear.tooth_thickness_angle();
+    new_angle -= (_angle) * (pitch_radius() / gear.pitch_radius());
+    new_angle += (a) * (pitch_radius() / gear.pitch_radius());
+    gear.angle(new_angle + a);
+    return gear;
+}
+
+
+
+// #################################################################
+
+
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+
+LPEGears::LPEGears(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    teeth(_("Teeth"), _("The number of teeth"), "teeth", &wr, this, 10),
+    phi(_("Phi"), _("???"), "phi", &wr, this, 5)
+{
+    registerParameter( dynamic_cast<Parameter *>(&teeth) );
+    registerParameter( dynamic_cast<Parameter *>(&phi) );
+}
+
+LPEGears::~LPEGears()
+{
+
+}
+
+std::vector<Geom::Path>
+LPEGears::doEffect (std::vector<Geom::Path> & path_in)
+{
+    std::vector<Geom::Path> path_out;
+    Geom::Path gearpath = path_in[0];
+
+    Geom::Path::iterator it(gearpath.begin());
+    if ( it == gearpath.end() ) return path_out;
+
+    Gear * gear = new Gear(teeth, 200.0, phi * M_PI / 180);
+    Geom::Point gear_centre = (*it).finalPoint();
+    gear->centre(gear_centre);
+    gear->angle(atan2((*it).initialPoint() - gear_centre));
+
+    it++; if ( it == gearpath.end() ) return path_out;
+    gear->pitch_radius(Geom::distance(gear_centre, (*it).finalPoint()));
+
+    path_out.push_back( gear->path());
+
+    for (it++ ; it != gearpath.end() ; it++) {
+        // iterate through Geom::Curve in path_in
+        Gear* gearnew = new Gear(gear->spawn( (*it).finalPoint() ));
+        path_out.push_back( gearnew->path() );
+        delete gear;
+        gear = gearnew;
+    }
+    delete gear;
+
+    return path_out;
+}
+
+
+} // namespace LivePathEffect
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index b43fbd95eee8153f12ddb73ad386db5415e60c4d..c3cea92301554c40ae954c5807e0d1fe177156fd 100644 (file)
@@ -1,38 +1,38 @@
-#ifndef INKSCAPE_LPE_GEARS_H\r
-#define INKSCAPE_LPE_GEARS_H\r
-\r
-/*\r
- * Inkscape::LPEGears\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
-*\r
-*\r
- */\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/parameter/parameter.h"\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-class LPEGears : public Effect {\r
-public:\r
-    LPEGears(LivePathEffectObject *lpeobject);\r
-    ~LPEGears();\r
-\r
-    std::vector<Geom::Path> doEffect (std::vector<Geom::Path> & path_in);\r
-\r
-private:\r
-    ScalarParam teeth;\r
-    ScalarParam phi;\r
-\r
-    LPEGears(const LPEGears&);\r
-    LPEGears& operator=(const LPEGears&);\r
-};\r
-\r
-}; //namespace LivePathEffect\r
-}; //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LPE_GEARS_H
+#define INKSCAPE_LPE_GEARS_H
+
+/*
+ * Inkscape::LPEGears
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+*
+*
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/parameter.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPEGears : public Effect {
+public:
+    LPEGears(LivePathEffectObject *lpeobject);
+    ~LPEGears();
+
+    std::vector<Geom::Path> doEffect (std::vector<Geom::Path> & path_in);
+
+private:
+    ScalarParam teeth;
+    ScalarParam phi;
+
+    LPEGears(const LPEGears&);
+    LPEGears& operator=(const LPEGears&);
+};
+
+}; //namespace LivePathEffect
+}; //namespace Inkscape
+
+#endif
index 31d4cfc2f556d3b7470e4d0814682cd8fcd4a1aa..d351c3553ee39f21927c763b59f59500f91d2d50 100644 (file)
-#define INKSCAPE_LPE_SKELETAL_STROKES_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/lpe-skeletalstrokes.h"\r
-#include "sp-shape.h"\r
-#include "display/curve.h"\r
-#include <libnr/n-art-bpath.h>\r
-#include "live_effects/n-art-bpath-2geom.h"\r
-#include "svg/svg.h"\r
-#include "ui/widget/scalar.h"\r
-\r
-#include <2geom/sbasis.h>\r
-#include <2geom/sbasis-geometric.h>\r
-#include <2geom/bezier-to-sbasis.h>\r
-#include <2geom/sbasis-to-bezier.h>\r
-#include <2geom/d2.h>\r
-#include <2geom/piecewise.h>\r
-\r
-#include <algorithm>\r
-using std::vector;\r
-\r
-\r
-/* Theory in e-mail from J.F. Barraud\r
-Let B be the skeleton path, and P the pattern (the path to be deformed).\r
-\r
-P is a map t --> P(t) = ( x(t), y(t) ).\r
-B is a map t --> B(t) = ( a(t), b(t) ).\r
-\r
-The first step is to re-parametrize B by its arc length: this is the parametrization in which a point p on B is located by its distance s from start. One obtains a new map s --> U(s) = (a'(s),b'(s)), that still describes the same path B, but where the distance along B from start to\r
-U(s) is s itself.\r
-\r
-We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90°. Call this normal vector N(s).\r
-\r
-The basic deformation associated to B is then given by:\r
-\r
-   (x,y) --> U(x)+y*N(x)\r
-\r
-(i.e. we go for distance x along the path, and then for distance y along the normal)\r
-\r
-Of course this formula needs some minor adaptations (as is it depends on the absolute position of P for instance, so a little translation is needed\r
-first) but I think we can first forget about them.\r
-*/\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-static const Util::EnumData<SkelCopyType> SkelCopyTypeData[SSCT_END] = {\r
-    {SSCT_SINGLE,               N_("Single"),               "single"},\r
-    {SSCT_SINGLE_STRETCHED,     N_("Single, stretched"),    "single_stretched"},\r
-    {SSCT_REPEATED,             N_("Repeated"),             "repeated"},\r
-    {SSCT_REPEATED_STRETCHED,   N_("Repeated, stretched"),  "repeated_stretched"}\r
-};\r
-static const Util::EnumDataConverter<SkelCopyType> SkelCopyTypeConverter(SkelCopyTypeData, SSCT_END);\r
-\r
-LPESkeletalStrokes::LPESkeletalStrokes(LivePathEffectObject *lpeobject) :\r
-    Effect(lpeobject),\r
-    pattern(_("Pattern source"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"),\r
-    copytype(_("Pattern copies"), _("How many pattern copies to place along the skeleton path"), "copytype", SkelCopyTypeConverter, &wr, this, SSCT_SINGLE_STRETCHED),\r
-    prop_scale(_("Width"), _("Width of the pattern"), "prop_scale", &wr, this, 1),\r
-    scale_y_rel(_("Width in units of length"), _("Scale the width of the pattern in units of its length"), "scale_y_rel", &wr, this, false),\r
-    spacing(_("Spacing"), _("Space between copies of the pattern"), "spacing", &wr, this, 0),\r
-    normal_offset(_("Normal offset"), "", "normal_offset", &wr, this, 0),\r
-    tang_offset(_("Tangential offset"), "", "tang_offset", &wr, this, 0),\r
-    vertical_pattern(_("Pattern is vertical"), "", "vertical_pattern", &wr, this, false)\r
-{\r
-    registerParameter( dynamic_cast<Parameter *>(&pattern) );\r
-    registerParameter( dynamic_cast<Parameter *>(&copytype) );\r
-    registerParameter( dynamic_cast<Parameter *>(&prop_scale) );\r
-    registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );\r
-//    registerParameter( dynamic_cast<Parameter *>(&spacing) );\r
-//    registerParameter( dynamic_cast<Parameter *>(&normal_offset) );\r
-//    registerParameter( dynamic_cast<Parameter *>(&tang_offset) );\r
-    registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) );\r
-\r
-    prop_scale.param_set_digits(3);\r
-    prop_scale.param_set_increments(0.01, 0.10);\r
-}\r
-\r
-LPESkeletalStrokes::~LPESkeletalStrokes()\r
-{\r
-\r
-}\r
-\r
-\r
-Geom::Piecewise<Geom::D2<Geom::SBasis> >\r
-LPESkeletalStrokes::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)\r
-{\r
-    using namespace Geom;\r
-\r
-/* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */\r
-\r
-    SkelCopyType type = copytype.get_value();\r
-\r
-    Piecewise<D2<SBasis> > uskeleton = arc_length_parametrization(Piecewise<D2<SBasis> >(pwd2_in),2,.1);\r
-    uskeleton = remove_short_cuts(uskeleton,.01);\r
-    Piecewise<D2<SBasis> > n = rot90(derivative(uskeleton));\r
-    n = force_continuity(remove_short_cuts(n,.1));\r
-\r
-    D2<Piecewise<SBasis> > patternd2 = make_cuts_independant(pattern);\r
-    Piecewise<SBasis> x = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]);\r
-    Piecewise<SBasis> y = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]);\r
-    Interval pattBnds = bounds_exact(x);\r
-    x -= pattBnds.min();\r
-    Interval pattBndsY = bounds_exact(y);\r
-    y -= (pattBndsY.max()+pattBndsY.min())/2;\r
-\r
-    int nbCopies = int(uskeleton.cuts.back()/pattBnds.extent());\r
-    double scaling = 1;\r
-\r
-    switch(type) {\r
-        case SSCT_REPEATED:\r
-            break;\r
-\r
-        case SSCT_SINGLE:\r
-            nbCopies = (nbCopies > 0) ? 1 : 0;\r
-            break;\r
-\r
-        case SSCT_SINGLE_STRETCHED:\r
-            nbCopies = 1;\r
-            scaling = uskeleton.cuts.back()/pattBnds.extent();\r
-            break;\r
-\r
-        case SSCT_REPEATED_STRETCHED:\r
-             scaling = uskeleton.cuts.back()/(((double)nbCopies)*pattBnds.extent());\r
-            break;\r
-\r
-        default:\r
-            return pwd2_in;\r
-    };\r
-\r
-    double pattWidth = pattBnds.extent() * scaling;\r
-\r
-    if (scaling != 1.0) {\r
-        x*=scaling;\r
-    }\r
-    if ( scale_y_rel.get_value() ) {\r
-        y*=(scaling*prop_scale);\r
-    } else {\r
-        if (prop_scale != 1.0) y *= prop_scale;\r
-    }\r
-\r
-    double offs = 0;\r
-    Piecewise<D2<SBasis> > output;\r
-    for (int i=0; i<nbCopies; i++){\r
-        output.concat(compose(uskeleton,x+offs)+y*compose(n,x+offs));\r
-        offs+=pattWidth;\r
-    }\r
-    return output;\r
-}\r
-\r
-\r
-} // namespace LivePathEffect\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LPE_SKELETAL_STROKES_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-skeletalstrokes.h"
+#include "sp-shape.h"
+#include "display/curve.h"
+#include <libnr/n-art-bpath.h>
+#include "live_effects/n-art-bpath-2geom.h"
+#include "svg/svg.h"
+#include "ui/widget/scalar.h"
+
+#include <2geom/sbasis.h>
+#include <2geom/sbasis-geometric.h>
+#include <2geom/bezier-to-sbasis.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
+#include <2geom/piecewise.h>
+
+#include <algorithm>
+using std::vector;
+
+
+/* Theory in e-mail from J.F. Barraud
+Let B be the skeleton path, and P the pattern (the path to be deformed).
+
+P is a map t --> P(t) = ( x(t), y(t) ).
+B is a map t --> B(t) = ( a(t), b(t) ).
+
+The first step is to re-parametrize B by its arc length: this is the parametrization in which a point p on B is located by its distance s from start. One obtains a new map s --> U(s) = (a'(s),b'(s)), that still describes the same path B, but where the distance along B from start to
+U(s) is s itself.
+
+We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90°. Call this normal vector N(s).
+
+The basic deformation associated to B is then given by:
+
+   (x,y) --> U(x)+y*N(x)
+
+(i.e. we go for distance x along the path, and then for distance y along the normal)
+
+Of course this formula needs some minor adaptations (as is it depends on the absolute position of P for instance, so a little translation is needed
+first) but I think we can first forget about them.
+*/
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+static const Util::EnumData<SkelCopyType> SkelCopyTypeData[SSCT_END] = {
+    {SSCT_SINGLE,               N_("Single"),               "single"},
+    {SSCT_SINGLE_STRETCHED,     N_("Single, stretched"),    "single_stretched"},
+    {SSCT_REPEATED,             N_("Repeated"),             "repeated"},
+    {SSCT_REPEATED_STRETCHED,   N_("Repeated, stretched"),  "repeated_stretched"}
+};
+static const Util::EnumDataConverter<SkelCopyType> SkelCopyTypeConverter(SkelCopyTypeData, SSCT_END);
+
+LPESkeletalStrokes::LPESkeletalStrokes(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    pattern(_("Pattern source"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"),
+    copytype(_("Pattern copies"), _("How many pattern copies to place along the skeleton path"), "copytype", SkelCopyTypeConverter, &wr, this, SSCT_SINGLE_STRETCHED),
+    prop_scale(_("Width"), _("Width of the pattern"), "prop_scale", &wr, this, 1),
+    scale_y_rel(_("Width in units of length"), _("Scale the width of the pattern in units of its length"), "scale_y_rel", &wr, this, false),
+    spacing(_("Spacing"), _("Space between copies of the pattern"), "spacing", &wr, this, 0),
+    normal_offset(_("Normal offset"), "", "normal_offset", &wr, this, 0),
+    tang_offset(_("Tangential offset"), "", "tang_offset", &wr, this, 0),
+    vertical_pattern(_("Pattern is vertical"), "", "vertical_pattern", &wr, this, false)
+{
+    registerParameter( dynamic_cast<Parameter *>(&pattern) );
+    registerParameter( dynamic_cast<Parameter *>(&copytype) );
+    registerParameter( dynamic_cast<Parameter *>(&prop_scale) );
+    registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );
+//    registerParameter( dynamic_cast<Parameter *>(&spacing) );
+//    registerParameter( dynamic_cast<Parameter *>(&normal_offset) );
+//    registerParameter( dynamic_cast<Parameter *>(&tang_offset) );
+    registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) );
+
+    prop_scale.param_set_digits(3);
+    prop_scale.param_set_increments(0.01, 0.10);
+}
+
+LPESkeletalStrokes::~LPESkeletalStrokes()
+{
+
+}
+
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPESkeletalStrokes::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)
+{
+    using namespace Geom;
+
+/* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */
+
+    SkelCopyType type = copytype.get_value();
+
+    Piecewise<D2<SBasis> > uskeleton = arc_length_parametrization(Piecewise<D2<SBasis> >(pwd2_in),2,.1);
+    uskeleton = remove_short_cuts(uskeleton,.01);
+    Piecewise<D2<SBasis> > n = rot90(derivative(uskeleton));
+    n = force_continuity(remove_short_cuts(n,.1));
+
+    D2<Piecewise<SBasis> > patternd2 = make_cuts_independant(pattern);
+    Piecewise<SBasis> x = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]);
+    Piecewise<SBasis> y = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]);
+    Interval pattBnds = bounds_exact(x);
+    x -= pattBnds.min();
+    Interval pattBndsY = bounds_exact(y);
+    y -= (pattBndsY.max()+pattBndsY.min())/2;
+
+    int nbCopies = int(uskeleton.cuts.back()/pattBnds.extent());
+    double scaling = 1;
+
+    switch(type) {
+        case SSCT_REPEATED:
+            break;
+
+        case SSCT_SINGLE:
+            nbCopies = (nbCopies > 0) ? 1 : 0;
+            break;
+
+        case SSCT_SINGLE_STRETCHED:
+            nbCopies = 1;
+            scaling = uskeleton.cuts.back()/pattBnds.extent();
+            break;
+
+        case SSCT_REPEATED_STRETCHED:
+             scaling = uskeleton.cuts.back()/(((double)nbCopies)*pattBnds.extent());
+            break;
+
+        default:
+            return pwd2_in;
+    };
+
+    double pattWidth = pattBnds.extent() * scaling;
+
+    if (scaling != 1.0) {
+        x*=scaling;
+    }
+    if ( scale_y_rel.get_value() ) {
+        y*=(scaling*prop_scale);
+    } else {
+        if (prop_scale != 1.0) y *= prop_scale;
+    }
+
+    double offs = 0;
+    Piecewise<D2<SBasis> > output;
+    for (int i=0; i<nbCopies; i++){
+        output.concat(compose(uskeleton,x+offs)+y*compose(n,x+offs));
+        offs+=pattWidth;
+    }
+    return output;
+}
+
+
+} // namespace LivePathEffect
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 919f09b8ec15d83c4a8f56bbc5ca862fb2823b15..64127ff0efa88084c03cbcd7bec88953b4880612 100644 (file)
@@ -1,54 +1,54 @@
-#ifndef INKSCAPE_LPE_SKELETAL_STROKES_H\r
-#define INKSCAPE_LPE_SKELETAL_STROKES_H\r
-\r
-/*\r
- * Inkscape::LPESkeletalStrokes\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/parameter/path.h"\r
-#include "live_effects/parameter/enum.h"\r
-#include "live_effects/parameter/bool.h"\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-enum SkelCopyType {\r
-    SSCT_SINGLE = 0,\r
-    SSCT_SINGLE_STRETCHED,\r
-    SSCT_REPEATED,\r
-    SSCT_REPEATED_STRETCHED,\r
-    SSCT_END // This must be last\r
-};\r
-\r
-class LPESkeletalStrokes : public Effect {\r
-public:\r
-    LPESkeletalStrokes(LivePathEffectObject *lpeobject);\r
-    ~LPESkeletalStrokes();\r
-\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);\r
-\r
-private:\r
-    PathParam  pattern;\r
-    EnumParam<SkelCopyType> copytype;\r
-    ScalarParam  prop_scale;\r
-    BoolParam scale_y_rel;\r
-    ScalarParam  spacing;\r
-    ScalarParam  normal_offset;\r
-    ScalarParam  tang_offset;\r
-    BoolParam    vertical_pattern;\r
-\r
-    void on_pattern_pasted();\r
-\r
-    LPESkeletalStrokes(const LPESkeletalStrokes&);\r
-    LPESkeletalStrokes& operator=(const LPESkeletalStrokes&);\r
-};\r
-\r
-}; //namespace LivePathEffect\r
-}; //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LPE_SKELETAL_STROKES_H
+#define INKSCAPE_LPE_SKELETAL_STROKES_H
+
+/*
+ * Inkscape::LPESkeletalStrokes
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/path.h"
+#include "live_effects/parameter/enum.h"
+#include "live_effects/parameter/bool.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+enum SkelCopyType {
+    SSCT_SINGLE = 0,
+    SSCT_SINGLE_STRETCHED,
+    SSCT_REPEATED,
+    SSCT_REPEATED_STRETCHED,
+    SSCT_END // This must be last
+};
+
+class LPESkeletalStrokes : public Effect {
+public:
+    LPESkeletalStrokes(LivePathEffectObject *lpeobject);
+    ~LPESkeletalStrokes();
+
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
+
+private:
+    PathParam  pattern;
+    EnumParam<SkelCopyType> copytype;
+    ScalarParam  prop_scale;
+    BoolParam scale_y_rel;
+    ScalarParam  spacing;
+    ScalarParam  normal_offset;
+    ScalarParam  tang_offset;
+    BoolParam    vertical_pattern;
+
+    void on_pattern_pasted();
+
+    LPESkeletalStrokes(const LPESkeletalStrokes&);
+    LPESkeletalStrokes& operator=(const LPESkeletalStrokes&);
+};
+
+}; //namespace LivePathEffect
+}; //namespace Inkscape
+
+#endif
index a2cd470b7250ccee7d2e06612836e5df078c1191..13356972e544b19809bf2571a15333656d4105d2 100644 (file)
-#define INKSCAPE_LPE_SKELETON_CPP\r
-/** \file\r
- * SVG <skeleton> implementation, used as an example for a base starting class\r
- * when implementing new LivePathEffects.\r
- *\r
- * In vi, three global search-and-replaces will let you rename everything\r
- * in this and the .h file:\r
- *\r
- *   :%s/SKELETON/YOURNAME/g\r
- *   :%s/Skeleton/Yourname/g\r
- *   :%s/skeleton/yourname/g\r
- */\r
-/*\r
- * Authors:\r
- *   Johan Engelen\r
-*\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/lpe-skeleton.h"\r
-#include "display/curve.h"\r
-#include <libnr/n-art-bpath.h>\r
-\r
-// You might need to include other 2geom files. You can add them here:\r
-#include <2geom/path.h>\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-LPESkeleton::LPESkeleton(LivePathEffectObject *lpeobject) :\r
-    Effect(lpeobject),\r
-    // initialise your parameters here:\r
-    number(_("Float parameter"), _("just a real number like 1.4!"), "svgname", &wr, this, 1.2)\r
-{\r
-    // register all your parameters here, so Inkscape knows which parameters this effect has:\r
-    registerParameter( dynamic_cast<Parameter *>(&number) );\r
-}\r
-\r
-LPESkeleton::~LPESkeleton()\r
-{\r
-\r
-}\r
-\r
-\r
-/* ########################\r
- *  Choose to implement one of the doEffect functions. You can delete or comment out the others.\r
-*/\r
-\r
-/*\r
-void\r
-LPESkeleton::doEffect (SPCurve * curve)\r
-{\r
-    // spice this up to make the effect actually *do* something!\r
-}\r
-\r
-NArtBpath *\r
-LPESkeleton::doEffect (NArtBpath * path_in)\r
-{\r
-        NArtBpath *path_out;\r
-        unsigned ret = 0;\r
-        while ( path_in[ret].code != NR_END ) {\r
-            ++ret;\r
-        }\r
-        unsigned len = ++ret;\r
-        path_out = g_new(NArtBpath, len);\r
-\r
-        memcpy(path_out, path_in, len * sizeof(NArtBpath));   // spice this up to make the effect actually *do* something!\r
-\r
-        return path_out;\r
-}\r
-\r
-std::vector<Geom::Path>\r
-LPESkeleton::doEffect (std::vector<Geom::Path> & path_in)\r
-{\r
-        std::vector<Geom::Path> path_out;\r
-\r
-        path_out = path_in;   // spice this up to make the effect actually *do* something!\r
-\r
-        return path_out;\r
-}\r
-*/\r
-\r
-Geom::Piecewise<Geom::D2<Geom::SBasis> >\r
-LPESkeleton::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)\r
-{\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > output;\r
-\r
-    output = pwd2_in;   // spice this up to make the effect actually *do* something!\r
-\r
-    return output;\r
-}\r
-\r
-/* ######################## */\r
-\r
-} //namespace LivePathEffect\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LPE_SKELETON_CPP
+/** \file
+ * SVG <skeleton> implementation, used as an example for a base starting class
+ * when implementing new LivePathEffects.
+ *
+ * In vi, three global search-and-replaces will let you rename everything
+ * in this and the .h file:
+ *
+ *   :%s/SKELETON/YOURNAME/g
+ *   :%s/Skeleton/Yourname/g
+ *   :%s/skeleton/yourname/g
+ */
+/*
+ * Authors:
+ *   Johan Engelen
+*
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-skeleton.h"
+#include "display/curve.h"
+#include <libnr/n-art-bpath.h>
+
+// You might need to include other 2geom files. You can add them here:
+#include <2geom/path.h>
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+LPESkeleton::LPESkeleton(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    // initialise your parameters here:
+    number(_("Float parameter"), _("just a real number like 1.4!"), "svgname", &wr, this, 1.2)
+{
+    // register all your parameters here, so Inkscape knows which parameters this effect has:
+    registerParameter( dynamic_cast<Parameter *>(&number) );
+}
+
+LPESkeleton::~LPESkeleton()
+{
+
+}
+
+
+/* ########################
+ *  Choose to implement one of the doEffect functions. You can delete or comment out the others.
+*/
+
+/*
+void
+LPESkeleton::doEffect (SPCurve * curve)
+{
+    // spice this up to make the effect actually *do* something!
+}
+
+NArtBpath *
+LPESkeleton::doEffect (NArtBpath * path_in)
+{
+        NArtBpath *path_out;
+        unsigned ret = 0;
+        while ( path_in[ret].code != NR_END ) {
+            ++ret;
+        }
+        unsigned len = ++ret;
+        path_out = g_new(NArtBpath, len);
+
+        memcpy(path_out, path_in, len * sizeof(NArtBpath));   // spice this up to make the effect actually *do* something!
+
+        return path_out;
+}
+
+std::vector<Geom::Path>
+LPESkeleton::doEffect (std::vector<Geom::Path> & path_in)
+{
+        std::vector<Geom::Path> path_out;
+
+        path_out = path_in;   // spice this up to make the effect actually *do* something!
+
+        return path_out;
+}
+*/
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPESkeleton::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)
+{
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > output;
+
+    output = pwd2_in;   // spice this up to make the effect actually *do* something!
+
+    return output;
+}
+
+/* ######################## */
+
+} //namespace LivePathEffect
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index cce9bde3e708aca46d3b5da85f65b114d054287c..816b8b7076f0cbca08b562f4b269f5355a3552e6 100644 (file)
@@ -1,47 +1,47 @@
-#ifndef INKSCAPE_LPE_SKELETON_H\r
-#define INKSCAPE_LPE_SKELETON_H\r
-\r
-/** \file\r
- * SVG <skeleton> implementation, see sp-skeleton.cpp.\r
- */\r
-\r
-/*\r
- * Authors:\r
- *   Johan Engelen\r
-*\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/parameter/parameter.h"\r
-#include "live_effects/parameter/point.h"\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-class LPESkeleton : public Effect {\r
-public:\r
-    LPESkeleton(LivePathEffectObject *lpeobject);\r
-    ~LPESkeleton();\r
-\r
-//  Choose to implement one of the doEffect functions. You can delete or comment out the others.\r
-//    void doEffect (SPCurve * curve);\r
-//    NArtBpath * doEffect (NArtBpath * path_in);\r
-//    std::vector<Geom::Path> doEffect (std::vector<Geom::Path> & path_in);\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);\r
-\r
-private:\r
-    // add the parameters for your effect here:\r
-    ScalarParam number;\r
-    // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist!\r
-\r
-    LPESkeleton(const LPESkeleton&);\r
-    LPESkeleton& operator=(const LPESkeleton&);\r
-};\r
-\r
-} //namespace LivePathEffect\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LPE_SKELETON_H
+#define INKSCAPE_LPE_SKELETON_H
+
+/** \file
+ * SVG <skeleton> implementation, see sp-skeleton.cpp.
+ */
+
+/*
+ * Authors:
+ *   Johan Engelen
+*
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/parameter.h"
+#include "live_effects/parameter/point.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPESkeleton : public Effect {
+public:
+    LPESkeleton(LivePathEffectObject *lpeobject);
+    ~LPESkeleton();
+
+//  Choose to implement one of the doEffect functions. You can delete or comment out the others.
+//    void doEffect (SPCurve * curve);
+//    NArtBpath * doEffect (NArtBpath * path_in);
+//    std::vector<Geom::Path> doEffect (std::vector<Geom::Path> & path_in);
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
+
+private:
+    // add the parameters for your effect here:
+    ScalarParam number;
+    // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist!
+
+    LPESkeleton(const LPESkeleton&);
+    LPESkeleton& operator=(const LPESkeleton&);
+};
+
+} //namespace LivePathEffect
+} //namespace Inkscape
+
+#endif
index c40d5fa20bc5f5b3dd77c1b2f9fabe03adbf5496..407e4399293e0620d13cdfecb1154729d105fa51 100644 (file)
@@ -1,55 +1,55 @@
-#define INKSCAPE_LPE_SLANT_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/lpe-slant.h"\r
-#include "display/curve.h"\r
-#include <libnr/n-art-bpath.h>\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-LPESlant::LPESlant(LivePathEffectObject *lpeobject) :\r
-    Effect(lpeobject),\r
-    factor(_("Slant factor"), _("y = y + x*(slant factor)"), "factor", &wr, this),\r
-    center(_("Center"), _("The x-coord of this point is around which the slant will happen"), "center", &wr, this)\r
-{\r
-    registerParameter( dynamic_cast<Parameter *>(&factor) );\r
-    registerParameter( dynamic_cast<Parameter *>(&center) );\r
-}\r
-\r
-LPESlant::~LPESlant()\r
-{\r
-}\r
-\r
-void\r
-LPESlant::doEffect(SPCurve * curve)\r
-{\r
-    NArtBpath *bpath = curve->_bpath;\r
-    int i = 0;\r
-    while(bpath[i].code != NR_END) {\r
-        bpath[i].y1 += (bpath[i].x1-center[Geom::X]) * factor;\r
-        bpath[i].y2 += (bpath[i].x2-center[Geom::X]) * factor;\r
-        bpath[i].y3 += (bpath[i].x3-center[Geom::X]) * factor;\r
-        i++;\r
-    }\r
-\r
-}\r
-\r
-}; //namespace LivePathEffect\r
-}; /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LPE_SLANT_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-slant.h"
+#include "display/curve.h"
+#include <libnr/n-art-bpath.h>
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+LPESlant::LPESlant(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    factor(_("Slant factor"), _("y = y + x*(slant factor)"), "factor", &wr, this),
+    center(_("Center"), _("The x-coord of this point is around which the slant will happen"), "center", &wr, this)
+{
+    registerParameter( dynamic_cast<Parameter *>(&factor) );
+    registerParameter( dynamic_cast<Parameter *>(&center) );
+}
+
+LPESlant::~LPESlant()
+{
+}
+
+void
+LPESlant::doEffect(SPCurve * curve)
+{
+    NArtBpath *bpath = curve->_bpath;
+    int i = 0;
+    while(bpath[i].code != NR_END) {
+        bpath[i].y1 += (bpath[i].x1-center[Geom::X]) * factor;
+        bpath[i].y2 += (bpath[i].x2-center[Geom::X]) * factor;
+        bpath[i].y3 += (bpath[i].x3-center[Geom::X]) * factor;
+        i++;
+    }
+
+}
+
+}; //namespace LivePathEffect
+}; /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 1f3ebcdb91c4736cad78d8ea3e486c0b69c6cb68..c92a37f809e33f01ac51abe85625a56e3ae29344 100644 (file)
@@ -1,40 +1,40 @@
-#ifndef INKSCAPE_LPE_SLANT_H\r
-#define INKSCAPE_LPE_SLANT_H\r
-\r
-/*\r
- * Inkscape::LPESlant\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/parameter/parameter.h"\r
-#include "live_effects/parameter/point.h"\r
-#include "ui/widget/registered-widget.h"\r
-\r
-\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-class LPESlant : public Effect {\r
-public:\r
-    LPESlant(LivePathEffectObject *lpeobject);\r
-    ~LPESlant();\r
-\r
-    void doEffect(SPCurve * curve);\r
-    \r
-private:\r
-    ScalarParam factor;\r
-    PointParam center;\r
-\r
-    LPESlant(const LPESlant&);\r
-    LPESlant& operator=(const LPESlant&);\r
-};\r
-\r
-}; //namespace LivePathEffect\r
-}; //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LPE_SLANT_H
+#define INKSCAPE_LPE_SLANT_H
+
+/*
+ * Inkscape::LPESlant
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/parameter.h"
+#include "live_effects/parameter/point.h"
+#include "ui/widget/registered-widget.h"
+
+
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPESlant : public Effect {
+public:
+    LPESlant(LivePathEffectObject *lpeobject);
+    ~LPESlant();
+
+    void doEffect(SPCurve * curve);
+    
+private:
+    ScalarParam factor;
+    PointParam center;
+
+    LPESlant(const LPESlant&);
+    LPESlant& operator=(const LPESlant&);
+};
+
+}; //namespace LivePathEffect
+}; //namespace Inkscape
+
+#endif
index 19f20b5a96af35dd5d56f6b4c4e19ddc3eb0abe4..d071050e905df4fe2b8a55e4c09a5139cc405d94 100644 (file)
@@ -1,96 +1,96 @@
-#define INKSCAPE_LPE_DOEFFECT_STACK_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/lpe-test-doEffect-stack.h"\r
-\r
-#include <2geom/piecewise.h>\r
-#include <vector>\r
-#include <libnr/n-art-bpath.h>\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-\r
-LPEdoEffectStackTest::LPEdoEffectStackTest(LivePathEffectObject *lpeobject) :\r
-    Effect(lpeobject),\r
-    step(_("Stack step"), (""), "step", &wr, this)\r
-{\r
-    registerParameter( dynamic_cast<Parameter *>(&step) );\r
-}\r
-\r
-LPEdoEffectStackTest::~LPEdoEffectStackTest()\r
-{\r
-\r
-}\r
-\r
-void\r
-LPEdoEffectStackTest::doEffect (SPCurve * curve)\r
-{\r
-    if (step >= 1) {\r
-        Effect::doEffect(curve);\r
-    } else {\r
-        // return here\r
-        return;\r
-    }\r
-}\r
-\r
-NArtBpath *\r
-LPEdoEffectStackTest::doEffect (NArtBpath * path_in)\r
-{\r
-    if (step >= 2) {\r
-        return Effect::doEffect(path_in);\r
-    } else {\r
-        // return here\r
-        NArtBpath *path_out;\r
-\r
-        unsigned ret = 0;\r
-        while ( path_in[ret].code != NR_END ) {\r
-            ++ret;\r
-        }\r
-        unsigned len = ++ret;\r
-\r
-        path_out = g_new(NArtBpath, len);\r
-        memcpy(path_out, path_in, len * sizeof(NArtBpath));\r
-        return path_out;\r
-    }\r
-}\r
-\r
-std::vector<Geom::Path>\r
-LPEdoEffectStackTest::doEffect (std::vector<Geom::Path> & path_in)\r
-{\r
-    if (step >= 3) {\r
-        return Effect::doEffect(path_in);\r
-    } else {\r
-        // return here\r
-        std::vector<Geom::Path> path_out = path_in;\r
-        return path_out;\r
-    }\r
-}\r
-\r
-Geom::Piecewise<Geom::D2<Geom::SBasis> > \r
-LPEdoEffectStackTest::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)\r
-{\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > output = pwd2_in;\r
-\r
-    return output;\r
-}\r
-\r
-\r
-} // namespace LivePathEffect\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LPE_DOEFFECT_STACK_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-test-doEffect-stack.h"
+
+#include <2geom/piecewise.h>
+#include <vector>
+#include <libnr/n-art-bpath.h>
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+
+LPEdoEffectStackTest::LPEdoEffectStackTest(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    step(_("Stack step"), (""), "step", &wr, this)
+{
+    registerParameter( dynamic_cast<Parameter *>(&step) );
+}
+
+LPEdoEffectStackTest::~LPEdoEffectStackTest()
+{
+
+}
+
+void
+LPEdoEffectStackTest::doEffect (SPCurve * curve)
+{
+    if (step >= 1) {
+        Effect::doEffect(curve);
+    } else {
+        // return here
+        return;
+    }
+}
+
+NArtBpath *
+LPEdoEffectStackTest::doEffect (NArtBpath * path_in)
+{
+    if (step >= 2) {
+        return Effect::doEffect(path_in);
+    } else {
+        // return here
+        NArtBpath *path_out;
+
+        unsigned ret = 0;
+        while ( path_in[ret].code != NR_END ) {
+            ++ret;
+        }
+        unsigned len = ++ret;
+
+        path_out = g_new(NArtBpath, len);
+        memcpy(path_out, path_in, len * sizeof(NArtBpath));
+        return path_out;
+    }
+}
+
+std::vector<Geom::Path>
+LPEdoEffectStackTest::doEffect (std::vector<Geom::Path> & path_in)
+{
+    if (step >= 3) {
+        return Effect::doEffect(path_in);
+    } else {
+        // return here
+        std::vector<Geom::Path> path_out = path_in;
+        return path_out;
+    }
+}
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> > 
+LPEdoEffectStackTest::doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)
+{
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > output = pwd2_in;
+
+    return output;
+}
+
+
+} // namespace LivePathEffect
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 5e990868e35b108dcf4be248a30b9425f87fe54c..0635bc06c5b881876ac122ef2aa0ba9ccd4567ae 100644 (file)
@@ -1,42 +1,42 @@
-#ifndef INKSCAPE_LPE_DOEFFECT_STACK_H\r
-#define INKSCAPE_LPE_DOEFFECT_STACK_H\r
-\r
-/*\r
- * Inkscape::LPEdoEffectStackTest\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
-*\r
-*   This effect is to test whether running up and down the doEffect stack does not change the original-d too much. \r
-*   i.e. for this effect, the output should match more or less exactly with the input.\r
-*\r
- */\r
-\r
-#include "live_effects/effect.h"\r
-#include "live_effects/parameter/parameter.h"\r
-\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-\r
-class LPEdoEffectStackTest : public Effect {\r
-public:\r
-    LPEdoEffectStackTest(LivePathEffectObject *lpeobject);\r
-    ~LPEdoEffectStackTest();\r
-\r
-    void                                     doEffect (SPCurve * curve);\r
-    NArtBpath *                              doEffect (NArtBpath * path_in);\r
-    std::vector<Geom::Path>                  doEffect (std::vector<Geom::Path> & path_in);\r
-    Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);\r
-\r
-private:\r
-    ScalarParam step;\r
-\r
-    LPEdoEffectStackTest(const LPEdoEffectStackTest&);\r
-    LPEdoEffectStackTest& operator=(const LPEdoEffectStackTest&);\r
-};\r
-\r
-}; //namespace LivePathEffect\r
-}; //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LPE_DOEFFECT_STACK_H
+#define INKSCAPE_LPE_DOEFFECT_STACK_H
+
+/*
+ * Inkscape::LPEdoEffectStackTest
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+*
+*   This effect is to test whether running up and down the doEffect stack does not change the original-d too much. 
+*   i.e. for this effect, the output should match more or less exactly with the input.
+*
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/parameter.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPEdoEffectStackTest : public Effect {
+public:
+    LPEdoEffectStackTest(LivePathEffectObject *lpeobject);
+    ~LPEdoEffectStackTest();
+
+    void                                     doEffect (SPCurve * curve);
+    NArtBpath *                              doEffect (NArtBpath * path_in);
+    std::vector<Geom::Path>                  doEffect (std::vector<Geom::Path> & path_in);
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
+
+private:
+    ScalarParam step;
+
+    LPEdoEffectStackTest(const LPEdoEffectStackTest&);
+    LPEdoEffectStackTest& operator=(const LPEdoEffectStackTest&);
+};
+
+}; //namespace LivePathEffect
+}; //namespace Inkscape
+
+#endif
index e4def4301198d110e0f11ce0ae4e556e186ac23a..6d37a0235fb17975ad8b2f0fbb77723a2b6b1dd4 100644 (file)
-/*\r
- * The reference corresponding to the inkscape:live-effect attribute\r
- *\r
- * Copyright (C) 2007 Johan Engelen\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information.\r
- */\r
-\r
-#include "enums.h"\r
-#include "live_effects/lpeobject-reference.h"\r
-#include "live_effects/lpeobject.h"\r
-\r
-#include "prefs-utils.h"\r
-#include "uri.h"\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-static void lpeobjectreference_href_changed(SPObject *old_ref, SPObject *ref, LPEObjectReference *lpeobjref);\r
-static void lpeobjectreference_delete_self(SPObject *deleted, LPEObjectReference *lpeobjref);\r
-static void lpeobjectreference_source_modified(SPObject *iSource, guint flags, LPEObjectReference *lpeobjref);\r
-\r
-LPEObjectReference::LPEObjectReference(SPObject* i_owner) : URIReference(i_owner)\r
-{\r
-    owner=i_owner;\r
-    lpeobject_href = NULL;\r
-    lpeobject_repr = NULL;\r
-    lpeobject = NULL;\r
-    _changed_connection = changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobjectreference_href_changed), this)); // listening to myself, this should be virtual instead\r
-\r
-    user_unlink = NULL;\r
-}\r
-\r
-LPEObjectReference::~LPEObjectReference(void)\r
-{\r
-    _changed_connection.disconnect(); // to do before unlinking\r
-\r
-    quit_listening();\r
-    unlink();\r
-}\r
-\r
-bool LPEObjectReference::_acceptObject(SPObject * const obj) const\r
-{\r
-    if (IS_LIVEPATHEFFECT(obj)) {\r
-        SPObject * const owner = getOwner();\r
-        /* Refuse references to us or to an ancestor. */\r
-        for ( SPObject *iter = owner ; iter ; iter = SP_OBJECT_PARENT(iter) ) {\r
-            if ( iter == obj ) {\r
-                return false;\r
-            }\r
-        }\r
-        return true;\r
-    } else {\r
-        return false;\r
-    }\r
-}\r
-\r
-void\r
-LPEObjectReference::link(char *to)\r
-{\r
-    if ( to == NULL ) {\r
-        quit_listening();\r
-        unlink();\r
-    } else {\r
-        if ( !lpeobject_href || ( strcmp(to, lpeobject_href) != 0 ) ) {\r
-            g_free(lpeobject_href);\r
-            lpeobject_href = g_strdup(to);\r
-            try {\r
-                attach(Inkscape::URI(to));\r
-            } catch (Inkscape::BadURIException &e) {\r
-                /* TODO: Proper error handling as per\r
-                 * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing.\r
-                 */\r
-                g_warning("%s", e.what());\r
-                detach();\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-LPEObjectReference::unlink(void)\r
-{\r
-    g_free(lpeobject_href);\r
-    lpeobject_href = NULL;\r
-    detach();\r
-}\r
-\r
-void\r
-LPEObjectReference::start_listening(LivePathEffectObject* to)\r
-{\r
-    if ( to == NULL ) {\r
-        return;\r
-    }\r
-    lpeobject = to;\r
-    lpeobject_repr = SP_OBJECT_REPR(to);\r
-    _delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&lpeobjectreference_delete_self), this));\r
-    _modified_connection = to->connectModified(sigc::bind<2>(sigc::ptr_fun(&lpeobjectreference_source_modified), this));\r
-}\r
-\r
-void\r
-LPEObjectReference::quit_listening(void)\r
-{\r
-    if ( lpeobject == NULL ) {\r
-        return;\r
-    }\r
-    _modified_connection.disconnect();\r
-    _delete_connection.disconnect();\r
-    lpeobject_repr = NULL;\r
-    lpeobject = NULL;\r
-}\r
-\r
-static void\r
-lpeobjectreference_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, LPEObjectReference *lpeobjref)\r
-{\r
-    lpeobjref->quit_listening();\r
-    LivePathEffectObject *refobj = LIVEPATHEFFECT( lpeobjref->getObject() );\r
-    if ( refobj ) {\r
-        lpeobjref->start_listening(refobj);\r
-    }\r
-\r
-    lpeobjref->owner->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);\r
-}\r
-\r
-static void\r
-lpeobjectreference_delete_self(SPObject */*deleted*/, LPEObjectReference *lpeobjref)\r
-{\r
-    guint const mode = prefs_get_int_attribute("options.cloneorphans", "value", SP_CLONE_ORPHANS_UNLINK);\r
-\r
-    if (mode == SP_CLONE_ORPHANS_UNLINK) {\r
-        // leave it be. just forget about the source\r
-        lpeobjref->quit_listening();\r
-        lpeobjref->unlink();\r
-        if (lpeobjref->user_unlink)\r
-            lpeobjref->user_unlink(lpeobjref->owner);\r
-    } else if (mode == SP_CLONE_ORPHANS_DELETE) {\r
-        lpeobjref->owner->deleteObject();\r
-    }\r
-}\r
-\r
-static void\r
-lpeobjectreference_source_modified(SPObject *iSource, guint flags, LPEObjectReference *lpeobjref)\r
-{\r
-    lpeobjref->owner->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);\r
-}\r
-\r
-} //namespace LivePathEffect\r
-\r
-} // namespace inkscape\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+/*
+ * The reference corresponding to the inkscape:live-effect attribute
+ *
+ * Copyright (C) 2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include "enums.h"
+#include "live_effects/lpeobject-reference.h"
+#include "live_effects/lpeobject.h"
+
+#include "prefs-utils.h"
+#include "uri.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+static void lpeobjectreference_href_changed(SPObject *old_ref, SPObject *ref, LPEObjectReference *lpeobjref);
+static void lpeobjectreference_delete_self(SPObject *deleted, LPEObjectReference *lpeobjref);
+static void lpeobjectreference_source_modified(SPObject *iSource, guint flags, LPEObjectReference *lpeobjref);
+
+LPEObjectReference::LPEObjectReference(SPObject* i_owner) : URIReference(i_owner)
+{
+    owner=i_owner;
+    lpeobject_href = NULL;
+    lpeobject_repr = NULL;
+    lpeobject = NULL;
+    _changed_connection = changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobjectreference_href_changed), this)); // listening to myself, this should be virtual instead
+
+    user_unlink = NULL;
+}
+
+LPEObjectReference::~LPEObjectReference(void)
+{
+    _changed_connection.disconnect(); // to do before unlinking
+
+    quit_listening();
+    unlink();
+}
+
+bool LPEObjectReference::_acceptObject(SPObject * const obj) const
+{
+    if (IS_LIVEPATHEFFECT(obj)) {
+        SPObject * const owner = getOwner();
+        /* Refuse references to us or to an ancestor. */
+        for ( SPObject *iter = owner ; iter ; iter = SP_OBJECT_PARENT(iter) ) {
+            if ( iter == obj ) {
+                return false;
+            }
+        }
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void
+LPEObjectReference::link(char *to)
+{
+    if ( to == NULL ) {
+        quit_listening();
+        unlink();
+    } else {
+        if ( !lpeobject_href || ( strcmp(to, lpeobject_href) != 0 ) ) {
+            g_free(lpeobject_href);
+            lpeobject_href = g_strdup(to);
+            try {
+                attach(Inkscape::URI(to));
+            } catch (Inkscape::BadURIException &e) {
+                /* TODO: Proper error handling as per
+                 * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing.
+                 */
+                g_warning("%s", e.what());
+                detach();
+            }
+        }
+    }
+}
+
+void
+LPEObjectReference::unlink(void)
+{
+    g_free(lpeobject_href);
+    lpeobject_href = NULL;
+    detach();
+}
+
+void
+LPEObjectReference::start_listening(LivePathEffectObject* to)
+{
+    if ( to == NULL ) {
+        return;
+    }
+    lpeobject = to;
+    lpeobject_repr = SP_OBJECT_REPR(to);
+    _delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&lpeobjectreference_delete_self), this));
+    _modified_connection = to->connectModified(sigc::bind<2>(sigc::ptr_fun(&lpeobjectreference_source_modified), this));
+}
+
+void
+LPEObjectReference::quit_listening(void)
+{
+    if ( lpeobject == NULL ) {
+        return;
+    }
+    _modified_connection.disconnect();
+    _delete_connection.disconnect();
+    lpeobject_repr = NULL;
+    lpeobject = NULL;
+}
+
+static void
+lpeobjectreference_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, LPEObjectReference *lpeobjref)
+{
+    lpeobjref->quit_listening();
+    LivePathEffectObject *refobj = LIVEPATHEFFECT( lpeobjref->getObject() );
+    if ( refobj ) {
+        lpeobjref->start_listening(refobj);
+    }
+
+    lpeobjref->owner->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
+static void
+lpeobjectreference_delete_self(SPObject */*deleted*/, LPEObjectReference *lpeobjref)
+{
+    guint const mode = prefs_get_int_attribute("options.cloneorphans", "value", SP_CLONE_ORPHANS_UNLINK);
+
+    if (mode == SP_CLONE_ORPHANS_UNLINK) {
+        // leave it be. just forget about the source
+        lpeobjref->quit_listening();
+        lpeobjref->unlink();
+        if (lpeobjref->user_unlink)
+            lpeobjref->user_unlink(lpeobjref->owner);
+    } else if (mode == SP_CLONE_ORPHANS_DELETE) {
+        lpeobjref->owner->deleteObject();
+    }
+}
+
+static void
+lpeobjectreference_source_modified(SPObject *iSource, guint flags, LPEObjectReference *lpeobjref)
+{
+    lpeobjref->owner->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
+} //namespace LivePathEffect
+
+} // namespace inkscape
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index ff7556d50c58dda5d01daf72f380f8badcdfbc44..ba652ff3ec90cf0a0df31516821f1999efc95e2d 100644 (file)
@@ -1,71 +1,71 @@
-#ifndef SEEN_LPEOBJECT_REFERENCE_H\r
-#define SEEN_LPEOBJECT_REFERENCE_H\r
-\r
-/*\r
- * The reference corresponding to the inkscape:live-effect attribute\r
- *\r
- * Copyright (C) 2007 Johan Engelen\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information.\r
- */\r
-\r
-#include <forward.h>\r
-#include <uri-references.h>\r
-#include <sigc++/sigc++.h>\r
-\r
-namespace Inkscape {\r
-namespace XML {\r
-struct Node;\r
-}\r
-}\r
-\r
-struct LivePathEffectObject;\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-class LPEObjectReference : public Inkscape::URIReference {\r
-public:\r
-    LPEObjectReference(SPObject *owner);\r
-    ~LPEObjectReference();\r
-\r
-    SPObject       *owner;\r
-\r
-    // concerning the LPEObject that is refered to:\r
-    gchar                *lpeobject_href;\r
-    Inkscape::XML::Node  *lpeobject_repr;\r
-    LivePathEffectObject *lpeobject;\r
-\r
-    sigc::connection _modified_connection;\r
-    sigc::connection _delete_connection;\r
-    sigc::connection _changed_connection;\r
-\r
-    void            link(char* to);\r
-    void            unlink(void);\r
-    void            start_listening(LivePathEffectObject* to);\r
-    void            quit_listening(void);\r
-\r
-    void (*user_unlink) (SPObject *user);\r
-\r
-protected:\r
-    bool _acceptObject(SPObject * const obj) const;\r
-\r
-};\r
-\r
-} //namespace LivePathEffect\r
-\r
-} // namespace inkscape\r
-\r
-#endif /* !SEEN_LPEOBJECT_REFERENCE_H */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#ifndef SEEN_LPEOBJECT_REFERENCE_H
+#define SEEN_LPEOBJECT_REFERENCE_H
+
+/*
+ * The reference corresponding to the inkscape:live-effect attribute
+ *
+ * Copyright (C) 2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include <forward.h>
+#include <uri-references.h>
+#include <sigc++/sigc++.h>
+
+namespace Inkscape {
+namespace XML {
+struct Node;
+}
+}
+
+struct LivePathEffectObject;
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+class LPEObjectReference : public Inkscape::URIReference {
+public:
+    LPEObjectReference(SPObject *owner);
+    ~LPEObjectReference();
+
+    SPObject       *owner;
+
+    // concerning the LPEObject that is refered to:
+    gchar                *lpeobject_href;
+    Inkscape::XML::Node  *lpeobject_repr;
+    LivePathEffectObject *lpeobject;
+
+    sigc::connection _modified_connection;
+    sigc::connection _delete_connection;
+    sigc::connection _changed_connection;
+
+    void            link(char* to);
+    void            unlink(void);
+    void            start_listening(LivePathEffectObject* to);
+    void            quit_listening(void);
+
+    void (*user_unlink) (SPObject *user);
+
+protected:
+    bool _acceptObject(SPObject * const obj) const;
+
+};
+
+} //namespace LivePathEffect
+
+} // namespace inkscape
+
+#endif /* !SEEN_LPEOBJECT_REFERENCE_H */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 8c45a4d3c98dd70e0a71e4d0afbfd627cd61967a..a8321b72d660641f281e172258e9c5a41948ff84 100644 (file)
-#define INKSCAPE_LIVEPATHEFFECT_OBJECT_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "xml/repr.h"\r
-#include "xml/node-event-vector.h"\r
-#include "sp-object.h"\r
-#include "attributes.h"\r
-\r
-#include "document.h"\r
-#include <glibmm/i18n.h>\r
-\r
-#include "live_effects/lpeobject.h"\r
-#include "live_effects/effect.h"\r
-\r
-//#define LIVEPATHEFFECT_VERBOSE\r
-\r
-static void livepatheffect_class_init(LivePathEffectObjectClass *klass);\r
-static void livepatheffect_init(LivePathEffectObject *stop);\r
-\r
-static void livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);\r
-static void livepatheffect_release(SPObject *object);\r
-\r
-static void livepatheffect_set(SPObject *object, unsigned key, gchar const *value);\r
-static Inkscape::XML::Node *livepatheffect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);\r
-\r
-static void livepatheffect_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data);\r
-\r
-static SPObjectClass *livepatheffect_parent_class;\r
-/**\r
- * Registers the LivePathEffect class with Gdk and returns its type number.\r
- */\r
-GType\r
-livepatheffect_get_type ()\r
-{\r
-    static GType livepatheffect_type = 0;\r
-\r
-    if (!livepatheffect_type) {\r
-        GTypeInfo livepatheffect_info = {\r
-            sizeof (LivePathEffectObjectClass),\r
-            NULL, NULL,\r
-            (GClassInitFunc) livepatheffect_class_init,\r
-            NULL, NULL,\r
-            sizeof (LivePathEffectObject),\r
-            16,\r
-            (GInstanceInitFunc) livepatheffect_init,\r
-            NULL,\r
-        };\r
-        livepatheffect_type = g_type_register_static (SP_TYPE_OBJECT, "LivePathEffectObject", &livepatheffect_info, (GTypeFlags)0);\r
-    }\r
-    return livepatheffect_type;\r
-}\r
-\r
-static Inkscape::XML::NodeEventVector const livepatheffect_repr_events = {\r
-    NULL, /* child_added */\r
-    NULL, /* child_removed */\r
-    livepatheffect_on_repr_attr_changed,\r
-    NULL, /* content_changed */\r
-    NULL  /* order_changed */\r
-};\r
-\r
-\r
-/**\r
- * Callback to initialize livepatheffect vtable.\r
- */\r
-static void \r
-livepatheffect_class_init(LivePathEffectObjectClass *klass)\r
-{\r
-    SPObjectClass *sp_object_class = (SPObjectClass *) klass;\r
-\r
-    livepatheffect_parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT);\r
-\r
-    sp_object_class->build = livepatheffect_build;\r
-    sp_object_class->release = livepatheffect_release;\r
-\r
-    sp_object_class->set = livepatheffect_set;\r
-    sp_object_class->write = livepatheffect_write;\r
-}\r
-\r
-/**\r
- * Callback to initialize livepatheffect object.\r
- */\r
-static void\r
-livepatheffect_init(LivePathEffectObject *lpeobj)\r
-{\r
-#ifdef LIVEPATHEFFECT_VERBOSE\r
-    g_message("Init livepatheffectobject");\r
-#endif\r
-    lpeobj->effecttype = Inkscape::LivePathEffect::INVALID_LPE;\r
-    lpeobj->lpe = NULL;\r
-\r
-    lpeobj->effecttype_set = false;\r
-}\r
-\r
-/**\r
- * Virtual build: set livepatheffect attributes from its associated XML node.\r
- */\r
-static void \r
-livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)\r
-{\r
-#ifdef LIVEPATHEFFECT_VERBOSE\r
-    g_message("Build livepatheffect");\r
-#endif\r
-    g_assert(object != NULL);\r
-    g_assert(SP_IS_OBJECT(object));\r
-\r
-    if (((SPObjectClass *) livepatheffect_parent_class)->build)\r
-        (* ((SPObjectClass *) livepatheffect_parent_class)->build)(object, document, repr);\r
-\r
-    sp_object_read_attr(object, "effect");\r
-\r
-    if (repr) {\r
-        repr->addListener (&livepatheffect_repr_events, object);\r
-    }\r
-\r
-    /* Register ourselves, is this necessary? */\r
-//    sp_document_add_resource(document, "path-effect", object);\r
-}\r
-\r
-/**\r
- * Virtual release of livepatheffect members before destruction.\r
- */\r
-static void\r
-livepatheffect_release(SPObject *object)\r
-{\r
-#ifdef LIVEPATHEFFECT_VERBOSE\r
-    g_print("Releasing livepatheffect");\r
-#endif\r
-\r
-    LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object);\r
-\r
-    SP_OBJECT_REPR(object)->removeListenerByData(object);\r
-\r
-\r
-/*\r
-    if (SP_OBJECT_DOCUMENT(object)) {\r
-        // Unregister ourselves\r
-        sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "livepatheffect", SP_OBJECT(object));\r
-    }\r
-\r
-    if (gradient->ref) {\r
-        gradient->modified_connection.disconnect();\r
-        gradient->ref->detach();\r
-        delete gradient->ref;\r
-        gradient->ref = NULL;\r
-    }\r
-\r
-    gradient->modified_connection.~connection();\r
-\r
-*/\r
-\r
-    if (lpeobj->lpe) {\r
-        delete lpeobj->lpe;\r
-        lpeobj->lpe = NULL;\r
-    }\r
-    lpeobj->effecttype = Inkscape::LivePathEffect::INVALID_LPE;\r
-\r
-    if (((SPObjectClass *) livepatheffect_parent_class)->release)\r
-        ((SPObjectClass *) livepatheffect_parent_class)->release(object);\r
-}\r
-\r
-/**\r
- * Virtual set: set attribute to value.\r
- */\r
-static void\r
-livepatheffect_set(SPObject *object, unsigned key, gchar const *value)\r
-{\r
-    LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object);\r
-#ifdef LIVEPATHEFFECT_VERBOSE\r
-    g_print("Set livepatheffect");\r
-#endif\r
-    switch (key) {\r
-        case SP_PROP_PATH_EFFECT:\r
-            if (lpeobj->lpe) {\r
-                delete lpeobj->lpe;\r
-                lpeobj->lpe = NULL;\r
-            }\r
-\r
-            if (value) {\r
-                lpeobj->effecttype = Inkscape::LivePathEffect::LPETypeConverter.get_id_from_key(value);\r
-                if (lpeobj->effecttype != Inkscape::LivePathEffect::INVALID_LPE) {\r
-                    lpeobj->lpe = Inkscape::LivePathEffect::Effect::New(lpeobj->effecttype, lpeobj);\r
-                }\r
-                lpeobj->effecttype_set = true;\r
-            } else {\r
-                lpeobj->effecttype = Inkscape::LivePathEffect::INVALID_LPE;\r
-                lpeobj->effecttype_set = false;\r
-            }\r
-            object->requestModified(SP_OBJECT_MODIFIED_FLAG);\r
-            break;\r
-    }\r
-\r
-    if (((SPObjectClass *) livepatheffect_parent_class)->set) {\r
-        ((SPObjectClass *) livepatheffect_parent_class)->set(object, key, value);\r
-    }\r
-}\r
-\r
-/**\r
- * Virtual write: write object attributes to repr.\r
- */\r
-static Inkscape::XML::Node *\r
-livepatheffect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)\r
-{\r
-#ifdef LIVEPATHEFFECT_VERBOSE\r
-    g_print("Write livepatheffect");\r
-#endif\r
-\r
-    LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object);\r
-\r
-    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {\r
-        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));\r
-        repr = xml_doc->createElement("inkscape:path-effect");\r
-    }\r
-\r
-    if ((flags & SP_OBJECT_WRITE_ALL) || lpeobj->effecttype_set)\r
-        repr->setAttribute("effect", Inkscape::LivePathEffect::LPETypeConverter.get_key(lpeobj->effecttype).c_str());\r
-\r
-//    lpeobj->lpe->write(repr); something like this.\r
-\r
-    if (((SPObjectClass *) livepatheffect_parent_class)->write)\r
-        (* ((SPObjectClass *) livepatheffect_parent_class)->write)(object, repr, flags);\r
-\r
-    return repr;\r
-}\r
-\r
-static void \r
-livepatheffect_on_repr_attr_changed ( Inkscape::XML::Node * repr, \r
-                                      const gchar *key, \r
-                                      const gchar *oldval, \r
-                                      const gchar *newval, \r
-                                      bool is_interactive, \r
-                                      void * data )\r
-{\r
-#ifdef LIVEPATHEFFECT_VERBOSE\r
-    g_print("livepatheffect_on_repr_attr_changed");\r
-#endif\r
-\r
-    if (!data)\r
-        return;\r
-\r
-    LivePathEffectObject *lpeobj = (LivePathEffectObject*) data;\r
-    if (!lpeobj->lpe) \r
-        return;\r
-\r
-    lpeobj->lpe->setParameter(repr, key, oldval, newval);\r
-\r
-    lpeobj->requestModified(SP_OBJECT_MODIFIED_FLAG);\r
-}\r
-\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_OBJECT_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "xml/repr.h"
+#include "xml/node-event-vector.h"
+#include "sp-object.h"
+#include "attributes.h"
+
+#include "document.h"
+#include <glibmm/i18n.h>
+
+#include "live_effects/lpeobject.h"
+#include "live_effects/effect.h"
+
+//#define LIVEPATHEFFECT_VERBOSE
+
+static void livepatheffect_class_init(LivePathEffectObjectClass *klass);
+static void livepatheffect_init(LivePathEffectObject *stop);
+
+static void livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void livepatheffect_release(SPObject *object);
+
+static void livepatheffect_set(SPObject *object, unsigned key, gchar const *value);
+static Inkscape::XML::Node *livepatheffect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static void livepatheffect_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data);
+
+static SPObjectClass *livepatheffect_parent_class;
+/**
+ * Registers the LivePathEffect class with Gdk and returns its type number.
+ */
+GType
+livepatheffect_get_type ()
+{
+    static GType livepatheffect_type = 0;
+
+    if (!livepatheffect_type) {
+        GTypeInfo livepatheffect_info = {
+            sizeof (LivePathEffectObjectClass),
+            NULL, NULL,
+            (GClassInitFunc) livepatheffect_class_init,
+            NULL, NULL,
+            sizeof (LivePathEffectObject),
+            16,
+            (GInstanceInitFunc) livepatheffect_init,
+            NULL,
+        };
+        livepatheffect_type = g_type_register_static (SP_TYPE_OBJECT, "LivePathEffectObject", &livepatheffect_info, (GTypeFlags)0);
+    }
+    return livepatheffect_type;
+}
+
+static Inkscape::XML::NodeEventVector const livepatheffect_repr_events = {
+    NULL, /* child_added */
+    NULL, /* child_removed */
+    livepatheffect_on_repr_attr_changed,
+    NULL, /* content_changed */
+    NULL  /* order_changed */
+};
+
+
+/**
+ * Callback to initialize livepatheffect vtable.
+ */
+static void 
+livepatheffect_class_init(LivePathEffectObjectClass *klass)
+{
+    SPObjectClass *sp_object_class = (SPObjectClass *) klass;
+
+    livepatheffect_parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT);
+
+    sp_object_class->build = livepatheffect_build;
+    sp_object_class->release = livepatheffect_release;
+
+    sp_object_class->set = livepatheffect_set;
+    sp_object_class->write = livepatheffect_write;
+}
+
+/**
+ * Callback to initialize livepatheffect object.
+ */
+static void
+livepatheffect_init(LivePathEffectObject *lpeobj)
+{
+#ifdef LIVEPATHEFFECT_VERBOSE
+    g_message("Init livepatheffectobject");
+#endif
+    lpeobj->effecttype = Inkscape::LivePathEffect::INVALID_LPE;
+    lpeobj->lpe = NULL;
+
+    lpeobj->effecttype_set = false;
+}
+
+/**
+ * Virtual build: set livepatheffect attributes from its associated XML node.
+ */
+static void 
+livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
+{
+#ifdef LIVEPATHEFFECT_VERBOSE
+    g_message("Build livepatheffect");
+#endif
+    g_assert(object != NULL);
+    g_assert(SP_IS_OBJECT(object));
+
+    if (((SPObjectClass *) livepatheffect_parent_class)->build)
+        (* ((SPObjectClass *) livepatheffect_parent_class)->build)(object, document, repr);
+
+    sp_object_read_attr(object, "effect");
+
+    if (repr) {
+        repr->addListener (&livepatheffect_repr_events, object);
+    }
+
+    /* Register ourselves, is this necessary? */
+//    sp_document_add_resource(document, "path-effect", object);
+}
+
+/**
+ * Virtual release of livepatheffect members before destruction.
+ */
+static void
+livepatheffect_release(SPObject *object)
+{
+#ifdef LIVEPATHEFFECT_VERBOSE
+    g_print("Releasing livepatheffect");
+#endif
+
+    LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object);
+
+    SP_OBJECT_REPR(object)->removeListenerByData(object);
+
+
+/*
+    if (SP_OBJECT_DOCUMENT(object)) {
+        // Unregister ourselves
+        sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "livepatheffect", SP_OBJECT(object));
+    }
+
+    if (gradient->ref) {
+        gradient->modified_connection.disconnect();
+        gradient->ref->detach();
+        delete gradient->ref;
+        gradient->ref = NULL;
+    }
+
+    gradient->modified_connection.~connection();
+
+*/
+
+    if (lpeobj->lpe) {
+        delete lpeobj->lpe;
+        lpeobj->lpe = NULL;
+    }
+    lpeobj->effecttype = Inkscape::LivePathEffect::INVALID_LPE;
+
+    if (((SPObjectClass *) livepatheffect_parent_class)->release)
+        ((SPObjectClass *) livepatheffect_parent_class)->release(object);
+}
+
+/**
+ * Virtual set: set attribute to value.
+ */
+static void
+livepatheffect_set(SPObject *object, unsigned key, gchar const *value)
+{
+    LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object);
+#ifdef LIVEPATHEFFECT_VERBOSE
+    g_print("Set livepatheffect");
+#endif
+    switch (key) {
+        case SP_PROP_PATH_EFFECT:
+            if (lpeobj->lpe) {
+                delete lpeobj->lpe;
+                lpeobj->lpe = NULL;
+            }
+
+            if (value) {
+                lpeobj->effecttype = Inkscape::LivePathEffect::LPETypeConverter.get_id_from_key(value);
+                if (lpeobj->effecttype != Inkscape::LivePathEffect::INVALID_LPE) {
+                    lpeobj->lpe = Inkscape::LivePathEffect::Effect::New(lpeobj->effecttype, lpeobj);
+                }
+                lpeobj->effecttype_set = true;
+            } else {
+                lpeobj->effecttype = Inkscape::LivePathEffect::INVALID_LPE;
+                lpeobj->effecttype_set = false;
+            }
+            object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+            break;
+    }
+
+    if (((SPObjectClass *) livepatheffect_parent_class)->set) {
+        ((SPObjectClass *) livepatheffect_parent_class)->set(object, key, value);
+    }
+}
+
+/**
+ * Virtual write: write object attributes to repr.
+ */
+static Inkscape::XML::Node *
+livepatheffect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+#ifdef LIVEPATHEFFECT_VERBOSE
+    g_print("Write livepatheffect");
+#endif
+
+    LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object);
+
+    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
+        repr = xml_doc->createElement("inkscape:path-effect");
+    }
+
+    if ((flags & SP_OBJECT_WRITE_ALL) || lpeobj->effecttype_set)
+        repr->setAttribute("effect", Inkscape::LivePathEffect::LPETypeConverter.get_key(lpeobj->effecttype).c_str());
+
+//    lpeobj->lpe->write(repr); something like this.
+
+    if (((SPObjectClass *) livepatheffect_parent_class)->write)
+        (* ((SPObjectClass *) livepatheffect_parent_class)->write)(object, repr, flags);
+
+    return repr;
+}
+
+static void 
+livepatheffect_on_repr_attr_changed ( Inkscape::XML::Node * repr, 
+                                      const gchar *key, 
+                                      const gchar *oldval, 
+                                      const gchar *newval, 
+                                      bool is_interactive, 
+                                      void * data )
+{
+#ifdef LIVEPATHEFFECT_VERBOSE
+    g_print("livepatheffect_on_repr_attr_changed");
+#endif
+
+    if (!data)
+        return;
+
+    LivePathEffectObject *lpeobj = (LivePathEffectObject*) data;
+    if (!lpeobj->lpe) 
+        return;
+
+    lpeobj->lpe->setParameter(repr, key, oldval, newval);
+
+    lpeobj->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index fff43cdcfd9584b1908b3e1f63a2edf442b116b0..c2e9fafa7949582827d1cc928f131444fac8ee8a 100644 (file)
@@ -1,52 +1,52 @@
-#ifndef INKSCAPE_LIVEPATHEFFECT_OBJECT_H\r
-#define INKSCAPE_LIVEPATHEFFECT_OBJECT_H\r
-\r
-/*\r
- * Inkscape::LivePathEffect\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
\r
-#include "sp-object.h"\r
-#include "effect.h"\r
-\r
-#define TYPE_LIVEPATHEFFECT  (livepatheffect_get_type())\r
-#define LIVEPATHEFFECT(o)    (G_TYPE_CHECK_INSTANCE_CAST((o), TYPE_LIVEPATHEFFECT, LivePathEffectObject))\r
-#define IS_LIVEPATHEFFECT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), TYPE_LIVEPATHEFFECT))\r
-\r
-/*\r
-namespace Inkscape {\r
-namespace LivePathEffect {\r
-    class Effect;\r
-};\r
-};\r
-*/\r
-\r
-struct LivePathEffectObject : public SPObject {\r
-    Inkscape::LivePathEffect::EffectType effecttype;  // fixme: i think this is not needed\r
-    Inkscape::LivePathEffect::Effect *lpe;\r
-\r
-    bool effecttype_set;\r
-};\r
-\r
-/// The LivePathEffect vtable.\r
-struct LivePathEffectObjectClass {\r
-    SPObjectClass parent_class;\r
-};\r
-\r
-GType livepatheffect_get_type();\r
-\r
-#endif\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_OBJECT_H
+#define INKSCAPE_LIVEPATHEFFECT_OBJECT_H
+
+/*
+ * Inkscape::LivePathEffect
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#include "sp-object.h"
+#include "effect.h"
+
+#define TYPE_LIVEPATHEFFECT  (livepatheffect_get_type())
+#define LIVEPATHEFFECT(o)    (G_TYPE_CHECK_INSTANCE_CAST((o), TYPE_LIVEPATHEFFECT, LivePathEffectObject))
+#define IS_LIVEPATHEFFECT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), TYPE_LIVEPATHEFFECT))
+
+/*
+namespace Inkscape {
+namespace LivePathEffect {
+    class Effect;
+};
+};
+*/
+
+struct LivePathEffectObject : public SPObject {
+    Inkscape::LivePathEffect::EffectType effecttype;  // fixme: i think this is not needed
+    Inkscape::LivePathEffect::Effect *lpe;
+
+    bool effecttype_set;
+};
+
+/// The LivePathEffect vtable.
+struct LivePathEffectObjectClass {
+    SPObjectClass parent_class;
+};
+
+GType livepatheffect_get_type();
+
+#endif
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 9e5b966eaffaf22a4074ca83f0dd6342d99aba94..72d4a69176da785cecd87f80d89a945d81249922 100644 (file)
-#define SEEN_LIBNR_N_ART_BPATH_2GEOM_CPP\r
-\r
-/** \file\r
- * Contains functions to convert from NArtBpath to 2geom's Path\r
- *\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
\r
-\r
-#include "live_effects/n-art-bpath-2geom.h"\r
-#include "svg/svg.h"\r
-#include <glib.h>\r
-#include <2geom/path.h>\r
-#include <2geom/svg-path.h>\r
-#include <2geom/svg-path-parser.h>\r
-#include <2geom/sbasis-to-bezier.h>\r
-\r
-#define LPE_USE_2GEOM_CONVERSION\r
-\r
-//##########################################################\r
-\r
-#include <iostream>\r
-#include <sstream>\r
-#include <string>\r
-#include <boost/format.hpp>\r
-\r
-static void curve_to_svgd(std::ostream & f, Geom::Curve const* c) {\r
-    if(Geom::LineSegment const *line_segment = dynamic_cast<Geom::LineSegment const  *>(c)) {\r
-        f << boost::format("L %g,%g ") % (*line_segment)[1][0] % (*line_segment)[1][1];\r
-    }\r
-    else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const  *>(c)) {\r
-        f << boost::format("Q %g,%g %g,%g ") % (*quadratic_bezier)[1][0] % (*quadratic_bezier)[1][0]  \r
-                % (*quadratic_bezier)[2][0] % (*quadratic_bezier)[2][1];\r
-    }\r
-    else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const  *>(c)) {\r
-        f << boost::format("C %g,%g %g,%g %g,%g ") \r
-                % (*cubic_bezier)[1][0] % (*cubic_bezier)[1][1] \r
-                % (*cubic_bezier)[2][0] % (*cubic_bezier)[2][1] \r
-                % (*cubic_bezier)[3][0] % (*cubic_bezier)[3][1];\r
-    }\r
-//    else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc *>(c)) {\r
-//        //get at the innards and spit them out as svgd\r
-//    }\r
-    else { \r
-        //this case handles sbasis as well as all other curve types\r
-        Geom::Path sbasis_path = Geom::path_from_sbasis(c->toSBasis(), 0.1);\r
-\r
-        //recurse to convert the new path resulting from the sbasis to svgd\r
-        for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) {\r
-            curve_to_svgd(f, &(*iter));\r
-        }\r
-    }\r
-}\r
-\r
-static void write_svgd(std::ostream & f, Geom::Path const &p) {\r
-    if(f == NULL) {\r
-        f << "ERRRRRRORRRRR";\r
-        return;\r
-    }\r
-\r
-    f << boost::format("M %g,%g ") % p.initialPoint()[0] % p.initialPoint()[1];\r
-    \r
-    for(Geom::Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) {\r
-        curve_to_svgd(f, &(*iter));\r
-    }\r
-    if(p.closed())\r
-        f << "Z ";\r
-}\r
-\r
-static void write_svgd(std::ostream & f, std::vector<Geom::Path> const &p) {\r
-    std::vector<Geom::Path>::const_iterator it(p.begin());\r
-    for(; it != p.end(); it++) {\r
-        write_svgd(f, *it);\r
-    }\r
-}\r
-\r
-//##########################################################\r
-#ifndef LPE_USE_2GEOM_CONVERSION\r
-\r
-static\r
-Geom::Point point(double *nums, int ix) {\r
-    return Geom::Point(nums[ix], nums[ix + 1]);\r
-}\r
-\r
-using namespace Geom;\r
-\r
-class OldPathBuilder {\r
-public:\r
-    OldPathBuilder(double const &c = Geom_EPSILON) : _current_path(NULL) {\r
-        _continuity_tollerance = c;\r
-    }\r
-\r
-    void startPathRel(Point const &p0) { startPath(p0 + _current_point); }\r
-    void startPath(Point const &p0) {\r
-        _pathset.push_back(Geom::Path());\r
-        _current_path = &_pathset.back();\r
-        _initial_point = _current_point = p0;\r
-    }\r
-\r
-    void pushLineRel(Point const &p0) { pushLine(p0 + _current_point); }\r
-    void pushLine(Point const &p1) {\r
-        if (!_current_path) startPath(_current_point);\r
-        _current_path->appendNew<LineSegment>(p1);\r
-        _current_point = p1;\r
-    }\r
-\r
-    void pushLineRel(Point const &p0, Point const &p1) { pushLine(p0 + _current_point, p1 + _current_point); }\r
-    void pushLine(Point const &p0, Point const &p1) {\r
-        if(p0 != _current_point) startPath(p0);\r
-        pushLine(p1);\r
-    }\r
-\r
-    void pushHorizontalRel(Coord y) { pushHorizontal(y + _current_point[1]); }\r
-    void pushHorizontal(Coord y) {\r
-        if (!_current_path) startPath(_current_point);\r
-        pushLine(Point(_current_point[0], y));\r
-    }\r
-\r
-    void pushVerticalRel(Coord x) { pushVertical(x + _current_point[0]); }\r
-    void pushVertical(Coord x) {\r
-        if (!_current_path) startPath(_current_point);\r
-        pushLine(Point(x, _current_point[1]));\r
-    }\r
-\r
-    void pushQuadraticRel(Point const &p1, Point const &p2) { pushQuadratic(p1 + _current_point, p2 + _current_point); }\r
-    void pushQuadratic(Point const &p1, Point const &p2) {\r
-        if (!_current_path) startPath(_current_point);\r
-        _current_path->appendNew<QuadraticBezier>(p1, p2);\r
-        _current_point = p2;\r
-    }\r
-\r
-    void pushQuadraticRel(Point const &p0, Point const &p1, Point const &p2) {\r
-        pushQuadratic(p0 + _current_point, p1 + _current_point, p2 + _current_point);\r
-    }\r
-    void pushQuadratic(Point const &p0, Point const &p1, Point const &p2) {\r
-        if(p0 != _current_point) startPath(p0);\r
-        pushQuadratic(p1, p2);\r
-    }\r
-\r
-    void pushCubicRel(Point const &p1, Point const &p2, Point const &p3) {\r
-        pushCubic(p1 + _current_point, p2 + _current_point, p3 + _current_point);\r
-    }\r
-    void pushCubic(Point const &p1, Point const &p2, Point const &p3) {\r
-        if (!_current_path) startPath(_current_point);\r
-        _current_path->appendNew<CubicBezier>(p1, p2, p3);\r
-        _current_point = p3;\r
-    }\r
-\r
-    void pushCubicRel(Point const &p0, Point const &p1, Point const &p2, Point const &p3) {\r
-        pushCubic(p0 + _current_point, p1 + _current_point, p2 + _current_point, p3 + _current_point);\r
-    }\r
-    void pushCubic(Point const &p0, Point const &p1, Point const &p2, Point const &p3) {\r
-        if(p0 != _current_point) startPath(p0);\r
-        pushCubic(p1, p2, p3);\r
-    }\r
-/*\r
-    void pushEllipseRel(Point const &radii, double rotation, bool large, bool sweep, Point const &end) {\r
-        pushEllipse(radii, rotation, large, sweep, end + _current_point);\r
-    }\r
-    void pushEllipse(Point const &radii, double rotation, bool large, bool sweep, Point const &end) {\r
-        if (!_current_path) startPath(_current_point);\r
-        _current_path->append(SVGEllipticalArc(_current_point, radii[0], radii[1], rotation, large, sweep, end));\r
-        _current_point = end;\r
-    }\r
-\r
-    void pushEllipseRel(Point const &initial, Point const &radii, double rotation, bool large, bool sweep, Point const &end) {\r
-        pushEllipse(initial + _current_point, radii, rotation, large, sweep, end + _current_point);\r
-    }\r
-    void pushEllipse(Point const &initial, Point const &radii, double rotation, bool large, bool sweep, Point const &end) {\r
-        if(initial != _current_point) startPath(initial);\r
-        pushEllipse(radii, rotation, large, sweep, end);\r
-    }*/\r
-    \r
-    void pushSBasis(SBasisCurve &sb) {\r
-        pushSBasis(sb.sbasis());\r
-    }\r
-    void pushSBasis(D2<SBasis> sb) {\r
-        Point initial = Point(sb[X][0][0], sb[Y][0][0]);\r
-        if (!_current_path) startPath(_current_point);\r
-        if (distance(initial, _current_point) > _continuity_tollerance) {\r
-            startPath(initial);\r
-        } else if (_current_point != initial) {\r
-            /* in this case there are three possible options\r
-               1. connect the points with tiny line segments\r
-                  this may well translate into bug reports from\r
-                  users claiming "duplicate or extraneous nodes"\r
-               2. fudge the initial point of the multidimsb\r
-                  we've chosen to do this here but question the \r
-                  numerical stability of this decision\r
-               3. translate the whole sbasis so that initial is coincident\r
-                  with _current_point. this could very well lead\r
-                  to an accumulation of error for paths that expect \r
-                  to meet in the end.\r
-               perhaps someday an option could be made to allow \r
-               the user to choose between these alternatives\r
-               if the need arises\r
-            */\r
-            sb[X][0][0] = _current_point[X];\r
-            sb[Y][0][0] = _current_point[Y]; \r
-        }\r
-        _current_path->append(sb);\r
-    }\r
-    \r
-    void closePath() {\r
-        if (_current_path) {\r
-            _current_path->close(true);\r
-            _current_path = NULL;\r
-        }\r
-        _current_point = _initial_point = Point();\r
-    }\r
-\r
-    std::vector<Path> const &peek() const { return _pathset; }\r
-\r
-private:\r
-    std::vector<Path> _pathset;\r
-    Path *_current_path;\r
-    Point _current_point;\r
-    Point _initial_point;\r
-    double _continuity_tollerance;\r
-};\r
-\r
-static\r
-std::vector<Geom::Path>\r
-read_svgd(std::istringstream & s) {\r
-    assert(s);\r
-\r
-    OldPathBuilder builder;\r
-\r
-    char mode = 0;\r
-\r
-    double nums[7];\r
-    int cur = 0;\r
-    while(!s.eof()) {\r
-        char ch;\r
-        s >> ch;\r
-        if((ch >= 'A' and ch <= 'Z') or (ch >= 'a' and ch <= 'z')) {\r
-            mode = ch;\r
-            cur = 0;\r
-        } else if (ch == ' ' or ch == '\t' or ch == '\n' or ch == '\r' or ch == ',')\r
-            continue;\r
-        else if ((ch >= '0' and ch <= '9') or ch == '-' or ch == '.' or ch == '+') {\r
-            s.unget();\r
-            //TODO: use something else, perhaps.  Unless the svg path number spec matches scan.\r
-            s >> nums[cur];\r
-            cur++;\r
-        }\r
-        \r
-        switch(mode) {\r
-        //FIXME: "If a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands."\r
-        case 'm':\r
-            if(cur >= 2) {\r
-                builder.startPathRel(point(nums, 0));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'M':\r
-            if(cur >= 2) {\r
-                builder.startPath(point(nums, 0));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'l':\r
-            if(cur >= 2) {\r
-                builder.pushLineRel(point(nums, 0));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'L':\r
-            if(cur >= 2) {\r
-                builder.pushLine(point(nums, 0));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'h':\r
-            if(cur >= 1) {\r
-                builder.pushHorizontalRel(nums[0]);\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'H':\r
-            if(cur >= 1) {\r
-                builder.pushHorizontal(nums[0]);\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'v':\r
-            if(cur >= 1) {\r
-                builder.pushVerticalRel(nums[0]);\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'V':\r
-            if(cur >= 1) {\r
-                builder.pushVertical(nums[0]);\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'c':\r
-            if(cur >= 6) {\r
-                builder.pushCubicRel(point(nums, 0), point(nums, 2), point(nums, 4));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'C':\r
-            if(cur >= 6) {\r
-                builder.pushCubic(point(nums, 0), point(nums, 2), point(nums, 4));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'q':\r
-            if(cur >= 4) {\r
-                builder.pushQuadraticRel(point(nums, 0), point(nums, 2));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'Q':\r
-            if(cur >= 4) {\r
-                builder.pushQuadratic(point(nums, 0), point(nums, 2));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'a':\r
-            if(cur >= 7) {\r
-                //builder.pushEllipseRel(point(nums, 0), nums[2], nums[3] > 0, nums[4] > 0, point(nums, 5));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'A':\r
-            if(cur >= 7) {\r
-                //builder.pushEllipse(point(nums, 0), nums[2], nums[3] > 0, nums[4] > 0, point(nums, 5));\r
-                cur = 0;\r
-            }\r
-            break;\r
-        case 'z':\r
-        case 'Z':\r
-            builder.closePath();\r
-            break;\r
-        }\r
-    }\r
-    return builder.peek();\r
-}\r
-\r
-\r
-#endif \r
-//##########################################################\r
-\r
-std::vector<Geom::Path>  \r
-SVGD_to_2GeomPath (char const *svgd)\r
-{\r
-    std::vector<Geom::Path> pathv;\r
-#ifdef LPE_USE_2GEOM_CONVERSION\r
-    try {\r
-        pathv = Geom::parse_svg_path(svgd);\r
-    }\r
-    catch (std::runtime_error e) {\r
-        g_warning("SVGPathParseError: %s", e.what());\r
-    }\r
-#else\r
-    std::istringstream ss;\r
-    std::string svgd_string = svgd;\r
-    ss.str(svgd_string);\r
-    pathv = read_svgd(ss);\r
-#endif\r
-    return pathv;\r
-}\r
-\r
-\r
-std::vector<Geom::Path>\r
-BPath_to_2GeomPath(NArtBpath const * bpath)\r
-{\r
-    std::vector<Geom::Path> pathv;\r
-    char *svgpath = sp_svg_write_path(bpath);\r
-    if (!svgpath) {\r
-        g_warning("BPath_to_2GeomPath - empty path returned");\r
-        return pathv;\r
-    }\r
-    pathv = SVGD_to_2GeomPath(svgpath);\r
-    g_free(svgpath);\r
-    return pathv;\r
-}\r
-\r
-char *\r
-SVGD_from_2GeomPath(std::vector<Geom::Path> const & path)\r
-{\r
-    std::ostringstream ss;\r
-    write_svgd(ss, path);\r
-    ss.flush();\r
-    std::string str = ss.str();\r
-    char * svgd = g_strdup(str.c_str());\r
-    return svgd;\r
-}\r
-\r
-NArtBpath *\r
-BPath_from_2GeomPath(std::vector<Geom::Path> const & path)\r
-{\r
-    char * svgd = SVGD_from_2GeomPath(path);\r
-    NArtBpath *bpath = sp_svg_read_path(svgd);\r
-    g_free(svgd);\r
-    return bpath;\r
-}\r
-\r
-\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define SEEN_LIBNR_N_ART_BPATH_2GEOM_CPP
+
+/** \file
+ * Contains functions to convert from NArtBpath to 2geom's Path
+ *
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/n-art-bpath-2geom.h"
+#include "svg/svg.h"
+#include <glib.h>
+#include <2geom/path.h>
+#include <2geom/svg-path.h>
+#include <2geom/svg-path-parser.h>
+#include <2geom/sbasis-to-bezier.h>
+
+#define LPE_USE_2GEOM_CONVERSION
+
+//##########################################################
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <boost/format.hpp>
+
+static void curve_to_svgd(std::ostream & f, Geom::Curve const* c) {
+    if(Geom::LineSegment const *line_segment = dynamic_cast<Geom::LineSegment const  *>(c)) {
+        f << boost::format("L %g,%g ") % (*line_segment)[1][0] % (*line_segment)[1][1];
+    }
+    else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const  *>(c)) {
+        f << boost::format("Q %g,%g %g,%g ") % (*quadratic_bezier)[1][0] % (*quadratic_bezier)[1][0]  
+                % (*quadratic_bezier)[2][0] % (*quadratic_bezier)[2][1];
+    }
+    else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const  *>(c)) {
+        f << boost::format("C %g,%g %g,%g %g,%g ") 
+                % (*cubic_bezier)[1][0] % (*cubic_bezier)[1][1] 
+                % (*cubic_bezier)[2][0] % (*cubic_bezier)[2][1] 
+                % (*cubic_bezier)[3][0] % (*cubic_bezier)[3][1];
+    }
+//    else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc *>(c)) {
+//        //get at the innards and spit them out as svgd
+//    }
+    else { 
+        //this case handles sbasis as well as all other curve types
+        Geom::Path sbasis_path = Geom::path_from_sbasis(c->toSBasis(), 0.1);
+
+        //recurse to convert the new path resulting from the sbasis to svgd
+        for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) {
+            curve_to_svgd(f, &(*iter));
+        }
+    }
+}
+
+static void write_svgd(std::ostream & f, Geom::Path const &p) {
+    if(f == NULL) {
+        f << "ERRRRRRORRRRR";
+        return;
+    }
+
+    f << boost::format("M %g,%g ") % p.initialPoint()[0] % p.initialPoint()[1];
+    
+    for(Geom::Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) {
+        curve_to_svgd(f, &(*iter));
+    }
+    if(p.closed())
+        f << "Z ";
+}
+
+static void write_svgd(std::ostream & f, std::vector<Geom::Path> const &p) {
+    std::vector<Geom::Path>::const_iterator it(p.begin());
+    for(; it != p.end(); it++) {
+        write_svgd(f, *it);
+    }
+}
+
+//##########################################################
+#ifndef LPE_USE_2GEOM_CONVERSION
+
+static
+Geom::Point point(double *nums, int ix) {
+    return Geom::Point(nums[ix], nums[ix + 1]);
+}
+
+using namespace Geom;
+
+class OldPathBuilder {
+public:
+    OldPathBuilder(double const &c = Geom_EPSILON) : _current_path(NULL) {
+        _continuity_tollerance = c;
+    }
+
+    void startPathRel(Point const &p0) { startPath(p0 + _current_point); }
+    void startPath(Point const &p0) {
+        _pathset.push_back(Geom::Path());
+        _current_path = &_pathset.back();
+        _initial_point = _current_point = p0;
+    }
+
+    void pushLineRel(Point const &p0) { pushLine(p0 + _current_point); }
+    void pushLine(Point const &p1) {
+        if (!_current_path) startPath(_current_point);
+        _current_path->appendNew<LineSegment>(p1);
+        _current_point = p1;
+    }
+
+    void pushLineRel(Point const &p0, Point const &p1) { pushLine(p0 + _current_point, p1 + _current_point); }
+    void pushLine(Point const &p0, Point const &p1) {
+        if(p0 != _current_point) startPath(p0);
+        pushLine(p1);
+    }
+
+    void pushHorizontalRel(Coord y) { pushHorizontal(y + _current_point[1]); }
+    void pushHorizontal(Coord y) {
+        if (!_current_path) startPath(_current_point);
+        pushLine(Point(_current_point[0], y));
+    }
+
+    void pushVerticalRel(Coord x) { pushVertical(x + _current_point[0]); }
+    void pushVertical(Coord x) {
+        if (!_current_path) startPath(_current_point);
+        pushLine(Point(x, _current_point[1]));
+    }
+
+    void pushQuadraticRel(Point const &p1, Point const &p2) { pushQuadratic(p1 + _current_point, p2 + _current_point); }
+    void pushQuadratic(Point const &p1, Point const &p2) {
+        if (!_current_path) startPath(_current_point);
+        _current_path->appendNew<QuadraticBezier>(p1, p2);
+        _current_point = p2;
+    }
+
+    void pushQuadraticRel(Point const &p0, Point const &p1, Point const &p2) {
+        pushQuadratic(p0 + _current_point, p1 + _current_point, p2 + _current_point);
+    }
+    void pushQuadratic(Point const &p0, Point const &p1, Point const &p2) {
+        if(p0 != _current_point) startPath(p0);
+        pushQuadratic(p1, p2);
+    }
+
+    void pushCubicRel(Point const &p1, Point const &p2, Point const &p3) {
+        pushCubic(p1 + _current_point, p2 + _current_point, p3 + _current_point);
+    }
+    void pushCubic(Point const &p1, Point const &p2, Point const &p3) {
+        if (!_current_path) startPath(_current_point);
+        _current_path->appendNew<CubicBezier>(p1, p2, p3);
+        _current_point = p3;
+    }
+
+    void pushCubicRel(Point const &p0, Point const &p1, Point const &p2, Point const &p3) {
+        pushCubic(p0 + _current_point, p1 + _current_point, p2 + _current_point, p3 + _current_point);
+    }
+    void pushCubic(Point const &p0, Point const &p1, Point const &p2, Point const &p3) {
+        if(p0 != _current_point) startPath(p0);
+        pushCubic(p1, p2, p3);
+    }
+/*
+    void pushEllipseRel(Point const &radii, double rotation, bool large, bool sweep, Point const &end) {
+        pushEllipse(radii, rotation, large, sweep, end + _current_point);
+    }
+    void pushEllipse(Point const &radii, double rotation, bool large, bool sweep, Point const &end) {
+        if (!_current_path) startPath(_current_point);
+        _current_path->append(SVGEllipticalArc(_current_point, radii[0], radii[1], rotation, large, sweep, end));
+        _current_point = end;
+    }
+
+    void pushEllipseRel(Point const &initial, Point const &radii, double rotation, bool large, bool sweep, Point const &end) {
+        pushEllipse(initial + _current_point, radii, rotation, large, sweep, end + _current_point);
+    }
+    void pushEllipse(Point const &initial, Point const &radii, double rotation, bool large, bool sweep, Point const &end) {
+        if(initial != _current_point) startPath(initial);
+        pushEllipse(radii, rotation, large, sweep, end);
+    }*/
+    
+    void pushSBasis(SBasisCurve &sb) {
+        pushSBasis(sb.sbasis());
+    }
+    void pushSBasis(D2<SBasis> sb) {
+        Point initial = Point(sb[X][0][0], sb[Y][0][0]);
+        if (!_current_path) startPath(_current_point);
+        if (distance(initial, _current_point) > _continuity_tollerance) {
+            startPath(initial);
+        } else if (_current_point != initial) {
+            /* in this case there are three possible options
+               1. connect the points with tiny line segments
+                  this may well translate into bug reports from
+                  users claiming "duplicate or extraneous nodes"
+               2. fudge the initial point of the multidimsb
+                  we've chosen to do this here but question the 
+                  numerical stability of this decision
+               3. translate the whole sbasis so that initial is coincident
+                  with _current_point. this could very well lead
+                  to an accumulation of error for paths that expect 
+                  to meet in the end.
+               perhaps someday an option could be made to allow 
+               the user to choose between these alternatives
+               if the need arises
+            */
+            sb[X][0][0] = _current_point[X];
+            sb[Y][0][0] = _current_point[Y]; 
+        }
+        _current_path->append(sb);
+    }
+    
+    void closePath() {
+        if (_current_path) {
+            _current_path->close(true);
+            _current_path = NULL;
+        }
+        _current_point = _initial_point = Point();
+    }
+
+    std::vector<Path> const &peek() const { return _pathset; }
+
+private:
+    std::vector<Path> _pathset;
+    Path *_current_path;
+    Point _current_point;
+    Point _initial_point;
+    double _continuity_tollerance;
+};
+
+static
+std::vector<Geom::Path>
+read_svgd(std::istringstream & s) {
+    assert(s);
+
+    OldPathBuilder builder;
+
+    char mode = 0;
+
+    double nums[7];
+    int cur = 0;
+    while(!s.eof()) {
+        char ch;
+        s >> ch;
+        if((ch >= 'A' and ch <= 'Z') or (ch >= 'a' and ch <= 'z')) {
+            mode = ch;
+            cur = 0;
+        } else if (ch == ' ' or ch == '\t' or ch == '\n' or ch == '\r' or ch == ',')
+            continue;
+        else if ((ch >= '0' and ch <= '9') or ch == '-' or ch == '.' or ch == '+') {
+            s.unget();
+            //TODO: use something else, perhaps.  Unless the svg path number spec matches scan.
+            s >> nums[cur];
+            cur++;
+        }
+        
+        switch(mode) {
+        //FIXME: "If a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands."
+        case 'm':
+            if(cur >= 2) {
+                builder.startPathRel(point(nums, 0));
+                cur = 0;
+            }
+            break;
+        case 'M':
+            if(cur >= 2) {
+                builder.startPath(point(nums, 0));
+                cur = 0;
+            }
+            break;
+        case 'l':
+            if(cur >= 2) {
+                builder.pushLineRel(point(nums, 0));
+                cur = 0;
+            }
+            break;
+        case 'L':
+            if(cur >= 2) {
+                builder.pushLine(point(nums, 0));
+                cur = 0;
+            }
+            break;
+        case 'h':
+            if(cur >= 1) {
+                builder.pushHorizontalRel(nums[0]);
+                cur = 0;
+            }
+            break;
+        case 'H':
+            if(cur >= 1) {
+                builder.pushHorizontal(nums[0]);
+                cur = 0;
+            }
+            break;
+        case 'v':
+            if(cur >= 1) {
+                builder.pushVerticalRel(nums[0]);
+                cur = 0;
+            }
+            break;
+        case 'V':
+            if(cur >= 1) {
+                builder.pushVertical(nums[0]);
+                cur = 0;
+            }
+            break;
+        case 'c':
+            if(cur >= 6) {
+                builder.pushCubicRel(point(nums, 0), point(nums, 2), point(nums, 4));
+                cur = 0;
+            }
+            break;
+        case 'C':
+            if(cur >= 6) {
+                builder.pushCubic(point(nums, 0), point(nums, 2), point(nums, 4));
+                cur = 0;
+            }
+            break;
+        case 'q':
+            if(cur >= 4) {
+                builder.pushQuadraticRel(point(nums, 0), point(nums, 2));
+                cur = 0;
+            }
+            break;
+        case 'Q':
+            if(cur >= 4) {
+                builder.pushQuadratic(point(nums, 0), point(nums, 2));
+                cur = 0;
+            }
+            break;
+        case 'a':
+            if(cur >= 7) {
+                //builder.pushEllipseRel(point(nums, 0), nums[2], nums[3] > 0, nums[4] > 0, point(nums, 5));
+                cur = 0;
+            }
+            break;
+        case 'A':
+            if(cur >= 7) {
+                //builder.pushEllipse(point(nums, 0), nums[2], nums[3] > 0, nums[4] > 0, point(nums, 5));
+                cur = 0;
+            }
+            break;
+        case 'z':
+        case 'Z':
+            builder.closePath();
+            break;
+        }
+    }
+    return builder.peek();
+}
+
+
+#endif 
+//##########################################################
+
+std::vector<Geom::Path>  
+SVGD_to_2GeomPath (char const *svgd)
+{
+    std::vector<Geom::Path> pathv;
+#ifdef LPE_USE_2GEOM_CONVERSION
+    try {
+        pathv = Geom::parse_svg_path(svgd);
+    }
+    catch (std::runtime_error e) {
+        g_warning("SVGPathParseError: %s", e.what());
+    }
+#else
+    std::istringstream ss;
+    std::string svgd_string = svgd;
+    ss.str(svgd_string);
+    pathv = read_svgd(ss);
+#endif
+    return pathv;
+}
+
+
+std::vector<Geom::Path>
+BPath_to_2GeomPath(NArtBpath const * bpath)
+{
+    std::vector<Geom::Path> pathv;
+    char *svgpath = sp_svg_write_path(bpath);
+    if (!svgpath) {
+        g_warning("BPath_to_2GeomPath - empty path returned");
+        return pathv;
+    }
+    pathv = SVGD_to_2GeomPath(svgpath);
+    g_free(svgpath);
+    return pathv;
+}
+
+char *
+SVGD_from_2GeomPath(std::vector<Geom::Path> const & path)
+{
+    std::ostringstream ss;
+    write_svgd(ss, path);
+    ss.flush();
+    std::string str = ss.str();
+    char * svgd = g_strdup(str.c_str());
+    return svgd;
+}
+
+NArtBpath *
+BPath_from_2GeomPath(std::vector<Geom::Path> const & path)
+{
+    char * svgd = SVGD_from_2GeomPath(path);
+    NArtBpath *bpath = sp_svg_read_path(svgd);
+    g_free(svgd);
+    return bpath;
+}
+
+
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 52b4cb9eee4190c7bf14a51e754b80f5d3cac291..21995656b88cf13b148661f8590b077f27586ef4 100644 (file)
@@ -1,33 +1,33 @@
-#ifndef SEEN_LIBNR_N_ART_BPATH_2GEOM_H\r
-#define SEEN_LIBNR_N_ART_BPATH_2GEOM_H\r
-\r
-/** \file\r
- * Contains functions to convert from NArtBpath to 2geom's Path\r
- *\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <vector>\r
-#include <2geom/path.h>\r
-#include <libnr/n-art-bpath.h>\r
-\r
-std::vector<Geom::Path>  SVGD_to_2GeomPath (char const *svgd);\r
-std::vector<Geom::Path>  BPath_to_2GeomPath (NArtBpath const *bpath);\r
-char *                   SVGD_from_2GeomPath(std::vector<Geom::Path> const & path);\r
-NArtBpath *              BPath_from_2GeomPath (std::vector<Geom::Path> const & path);\r
-\r
-\r
-#endif /* !SEEN_LIBNR_N_ART_BPATH_2GEOM_H */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#ifndef SEEN_LIBNR_N_ART_BPATH_2GEOM_H
+#define SEEN_LIBNR_N_ART_BPATH_2GEOM_H
+
+/** \file
+ * Contains functions to convert from NArtBpath to 2geom's Path
+ *
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <vector>
+#include <2geom/path.h>
+#include <libnr/n-art-bpath.h>
+
+std::vector<Geom::Path>  SVGD_to_2GeomPath (char const *svgd);
+std::vector<Geom::Path>  BPath_to_2GeomPath (NArtBpath const *bpath);
+char *                   SVGD_from_2GeomPath(std::vector<Geom::Path> const & path);
+NArtBpath *              BPath_from_2GeomPath (std::vector<Geom::Path> const & path);
+
+
+#endif /* !SEEN_LIBNR_N_ART_BPATH_2GEOM_H */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 36806242f85f9ada9b5c1f628cec11e561483ee2..78ce179391264dc541eb6b59f80120dc369a24c6 100644 (file)
@@ -1,93 +1,93 @@
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_BOOL_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/parameter/bool.h"\r
-#include "live_effects/effect.h"\r
-#include "svg/svg.h"\r
-#include "svg/stringstream.h"\r
-#include <gtkmm.h>\r
-#include "widgets/icon.h"\r
-\r
-#include "inkscape.h"\r
-#include "verbs.h"\r
-#include "helper-fns.h"\r
-\r
-#define noLPEBOOLPARAM_DEBUG\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip,\r
-                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
-                      Effect* effect, bool default_value )\r
-    : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value)\r
-{\r
-    checkwdg = NULL;\r
-}\r
-\r
-BoolParam::~BoolParam()\r
-{\r
-    if (checkwdg)\r
-        delete checkwdg;\r
-}\r
-\r
-void\r
-BoolParam::param_set_default()\r
-{\r
-    param_setValue(defvalue);\r
-}\r
-\r
-bool\r
-BoolParam::param_readSVGValue(const gchar * strvalue)\r
-{\r
-    param_setValue(helperfns_read_bool(strvalue, defvalue));\r
-    return true; // not correct: if value is unacceptable, should return false!\r
-}\r
-\r
-gchar *\r
-BoolParam::param_writeSVGValue() const\r
-{\r
-    gchar * str = g_strdup(value ? "true" : "false");\r
-    return str;\r
-}\r
-\r
-Gtk::Widget *\r
-BoolParam::param_getWidget()\r
-{\r
-    if (!checkwdg) {\r
-        checkwdg = new Inkscape::UI::Widget::RegisteredCheckButton();\r
-        checkwdg->init(param_label, param_tooltip, param_key, *param_wr, false, param_effect->getRepr(), param_effect->getSPDoc());\r
-        checkwdg->setActive(value);\r
-        checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter"));\r
-    }\r
-    return dynamic_cast<Gtk::Widget *> (checkwdg->_button);\r
-}\r
-\r
-void\r
-BoolParam::param_setValue(bool newvalue)\r
-{\r
-    value = newvalue;\r
-    if (checkwdg)\r
-        checkwdg->setActive(newvalue);\r
-}\r
-\r
-} /* namespace LivePathEffect */\r
-\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_BOOL_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/bool.h"
+#include "live_effects/effect.h"
+#include "svg/svg.h"
+#include "svg/stringstream.h"
+#include <gtkmm.h>
+#include "widgets/icon.h"
+
+#include "inkscape.h"
+#include "verbs.h"
+#include "helper-fns.h"
+
+#define noLPEBOOLPARAM_DEBUG
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip,
+                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+                      Effect* effect, bool default_value )
+    : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value)
+{
+    checkwdg = NULL;
+}
+
+BoolParam::~BoolParam()
+{
+    if (checkwdg)
+        delete checkwdg;
+}
+
+void
+BoolParam::param_set_default()
+{
+    param_setValue(defvalue);
+}
+
+bool
+BoolParam::param_readSVGValue(const gchar * strvalue)
+{
+    param_setValue(helperfns_read_bool(strvalue, defvalue));
+    return true; // not correct: if value is unacceptable, should return false!
+}
+
+gchar *
+BoolParam::param_writeSVGValue() const
+{
+    gchar * str = g_strdup(value ? "true" : "false");
+    return str;
+}
+
+Gtk::Widget *
+BoolParam::param_getWidget()
+{
+    if (!checkwdg) {
+        checkwdg = new Inkscape::UI::Widget::RegisteredCheckButton();
+        checkwdg->init(param_label, param_tooltip, param_key, *param_wr, false, param_effect->getRepr(), param_effect->getSPDoc());
+        checkwdg->setActive(value);
+        checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter"));
+    }
+    return dynamic_cast<Gtk::Widget *> (checkwdg->_button);
+}
+
+void
+BoolParam::param_setValue(bool newvalue)
+{
+    value = newvalue;
+    if (checkwdg)
+        checkwdg->setActive(newvalue);
+}
+
+} /* namespace LivePathEffect */
+
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 0a29a94397093d2a151a2365268349742c1a63e4..13dc57b6c56510823003b7aaea16650e03dcd81c 100644 (file)
@@ -1,59 +1,59 @@
-#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_BOOL_H\r
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_BOOL_H\r
-\r
-/*\r
- * Inkscape::LivePathEffectParameters\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <glib/gtypes.h>\r
-\r
-#include "ui/widget/registry.h"\r
-#include "ui/widget/registered-widget.h"\r
-\r
-#include "live_effects/parameter/parameter.h"\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-\r
-class BoolParam : public Parameter {\r
-public:\r
-    BoolParam( const Glib::ustring& label,\r
-               const Glib::ustring& tip,\r
-               const Glib::ustring& key,\r
-               Inkscape::UI::Widget::Registry* wr,\r
-               Effect* effect,\r
-               bool default_value = false);\r
-    virtual ~BoolParam();\r
-\r
-    virtual Gtk::Widget * param_getWidget();\r
-\r
-    virtual bool param_readSVGValue(const gchar * strvalue);\r
-    virtual gchar * param_writeSVGValue() const;\r
-\r
-    void param_setValue(bool newvalue);\r
-    virtual void param_set_default();\r
-\r
-    bool get_value() { return value; };\r
-\r
-private:\r
-    BoolParam(const BoolParam&);\r
-    BoolParam& operator=(const BoolParam&);\r
-\r
-    Inkscape::UI::Widget::RegisteredCheckButton * checkwdg;\r
-\r
-    bool value;\r
-    bool defvalue;\r
-};\r
-\r
-\r
-} //namespace LivePathEffect\r
-\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_BOOL_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_BOOL_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gtypes.h>
+
+#include "ui/widget/registry.h"
+#include "ui/widget/registered-widget.h"
+
+#include "live_effects/parameter/parameter.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+
+class BoolParam : public Parameter {
+public:
+    BoolParam( const Glib::ustring& label,
+               const Glib::ustring& tip,
+               const Glib::ustring& key,
+               Inkscape::UI::Widget::Registry* wr,
+               Effect* effect,
+               bool default_value = false);
+    virtual ~BoolParam();
+
+    virtual Gtk::Widget * param_getWidget();
+
+    virtual bool param_readSVGValue(const gchar * strvalue);
+    virtual gchar * param_writeSVGValue() const;
+
+    void param_setValue(bool newvalue);
+    virtual void param_set_default();
+
+    bool get_value() { return value; };
+
+private:
+    BoolParam(const BoolParam&);
+    BoolParam& operator=(const BoolParam&);
+
+    Inkscape::UI::Widget::RegisteredCheckButton * checkwdg;
+
+    bool value;
+    bool defvalue;
+};
+
+
+} //namespace LivePathEffect
+
+} //namespace Inkscape
+
+#endif
index 4fd948ee6eb793f1674e3771ef12c62cb4f599c2..4ee28f8959c74031273e4763964274d616023cc2 100644 (file)
-#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ENUM_H\r
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ENUM_H\r
-\r
-/*\r
- * Inkscape::LivePathEffectParameters\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <glib/gtypes.h>\r
-\r
-#include "ui/widget/registry.h"\r
-#include "ui/widget/registered-enums.h"\r
-#include <gtkmm/tooltips.h>\r
-\r
-#include "live_effects/parameter/parameter.h"\r
-#include "verbs.h"\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-template<typename E> class EnumParam : public Parameter {\r
-public:\r
-    EnumParam(  const Glib::ustring& label,\r
-                const Glib::ustring& tip,\r
-                const Glib::ustring& key,\r
-                const Util::EnumDataConverter<E>& c,\r
-                Inkscape::UI::Widget::Registry* wr,\r
-                Effect* effect,\r
-                E default_value)\r
-        : Parameter(label, tip, key, wr, effect)\r
-    {\r
-        regenum = NULL;\r
-        enumdataconv = &c;\r
-        defvalue = default_value;\r
-        value = defvalue;\r
-    };\r
-    ~EnumParam() {\r
-        if (regenum)\r
-            delete regenum;\r
-    };\r
-\r
-    Gtk::Widget * param_getWidget() {\r
-        if (!regenum) {\r
-            regenum = new Inkscape::UI::Widget::RegisteredEnum<E>();\r
-            regenum->init(param_label, param_tooltip, param_key, *enumdataconv, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());\r
-            regenum->combobox()->set_active_by_id(value);\r
-            regenum->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change enum parameter"));\r
-        }\r
-        return dynamic_cast<Gtk::Widget *> (regenum->labelled);\r
-    };\r
-\r
-    bool param_readSVGValue(const gchar * strvalue) {\r
-        if (!strvalue) {\r
-            param_set_default();\r
-            return true;\r
-        }\r
-\r
-        param_set_value( enumdataconv->get_id_from_key(Glib::ustring(strvalue)) );\r
-\r
-        return true;\r
-    };\r
-    gchar * param_writeSVGValue() const {\r
-        gchar * str = g_strdup( enumdataconv->get_key(value).c_str() );\r
-        return str;\r
-    };\r
-\r
-    E get_value() const {\r
-        return value;\r
-    }\r
-\r
-    void param_set_default() {\r
-        param_set_value(defvalue);\r
-    }\r
-\r
-    void param_set_value(E val) {\r
-        value = val;\r
-        if (regenum)\r
-            regenum->combobox()->set_active_by_id(value);\r
-    }\r
-\r
-private:\r
-    EnumParam(const EnumParam&);\r
-    EnumParam& operator=(const EnumParam&);\r
-\r
-    UI::Widget::RegisteredEnum<E> * regenum;\r
-    E value;\r
-    E defvalue;\r
-\r
-    const Util::EnumDataConverter<E> * enumdataconv;\r
-};\r
-\r
-\r
-}; //namespace LivePathEffect\r
-\r
-}; //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ENUM_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ENUM_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gtypes.h>
+
+#include "ui/widget/registry.h"
+#include "ui/widget/registered-enums.h"
+#include <gtkmm/tooltips.h>
+
+#include "live_effects/parameter/parameter.h"
+#include "verbs.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+template<typename E> class EnumParam : public Parameter {
+public:
+    EnumParam(  const Glib::ustring& label,
+                const Glib::ustring& tip,
+                const Glib::ustring& key,
+                const Util::EnumDataConverter<E>& c,
+                Inkscape::UI::Widget::Registry* wr,
+                Effect* effect,
+                E default_value)
+        : Parameter(label, tip, key, wr, effect)
+    {
+        regenum = NULL;
+        enumdataconv = &c;
+        defvalue = default_value;
+        value = defvalue;
+    };
+    ~EnumParam() {
+        if (regenum)
+            delete regenum;
+    };
+
+    Gtk::Widget * param_getWidget() {
+        if (!regenum) {
+            regenum = new Inkscape::UI::Widget::RegisteredEnum<E>();
+            regenum->init(param_label, param_tooltip, param_key, *enumdataconv, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());
+            regenum->combobox()->set_active_by_id(value);
+            regenum->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change enum parameter"));
+        }
+        return dynamic_cast<Gtk::Widget *> (regenum->labelled);
+    };
+
+    bool param_readSVGValue(const gchar * strvalue) {
+        if (!strvalue) {
+            param_set_default();
+            return true;
+        }
+
+        param_set_value( enumdataconv->get_id_from_key(Glib::ustring(strvalue)) );
+
+        return true;
+    };
+    gchar * param_writeSVGValue() const {
+        gchar * str = g_strdup( enumdataconv->get_key(value).c_str() );
+        return str;
+    };
+
+    E get_value() const {
+        return value;
+    }
+
+    void param_set_default() {
+        param_set_value(defvalue);
+    }
+
+    void param_set_value(E val) {
+        value = val;
+        if (regenum)
+            regenum->combobox()->set_active_by_id(value);
+    }
+
+private:
+    EnumParam(const EnumParam&);
+    EnumParam& operator=(const EnumParam&);
+
+    UI::Widget::RegisteredEnum<E> * regenum;
+    E value;
+    E defvalue;
+
+    const Util::EnumDataConverter<E> * enumdataconv;
+};
+
+
+}; //namespace LivePathEffect
+
+}; //namespace Inkscape
+
+#endif
index faed7c389d6cce0d725544f3e157dcada07a2fce..efca9908d257feeb46e71880b9e9ac2795ab7c34 100644 (file)
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/parameter/parameter.h"\r
-#include "live_effects/effect.h"\r
-#include "svg/svg.h"\r
-#include "libnr/nr-values.h"\r
-\r
-#include <gtkmm.h>\r
-#include "ui/widget/scalar.h"\r
-\r
-#include "svg/stringstream.h"\r
-\r
-#include "verbs.h"\r
-\r
-#define noLPEREALPARAM_DEBUG\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-\r
-Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip,\r
-                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
-                      Effect* effect )\r
-{\r
-    param_label = label;\r
-    param_tooltip = tip;\r
-    param_key = key;\r
-    param_wr = wr;\r
-    param_effect = effect;\r
-}\r
-\r
-\r
-\r
-/*###########################################\r
- *   REAL PARAM\r
- */\r
-ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip,\r
-                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
-                      Effect* effect, gdouble default_value)\r
-    : Parameter(label, tip, key, wr, effect)\r
-{\r
-    defvalue = default_value;\r
-    value = defvalue;\r
-    min = -NR_HUGE;\r
-    max = NR_HUGE;\r
-    integer = false;\r
-    rsu = NULL;\r
-    inc_step = 0.1;\r
-    inc_page = 1;\r
-    digits = 2;\r
-}\r
-\r
-ScalarParam::~ScalarParam()\r
-{\r
-    if (rsu)\r
-        delete rsu;\r
-}\r
-\r
-bool\r
-ScalarParam::param_readSVGValue(const gchar * strvalue)\r
-{\r
-    double newval;\r
-    unsigned int success = sp_svg_number_read_d(strvalue, &newval);\r
-    if (success == 1) {\r
-        param_set_value(newval);\r
-        return true;\r
-    }\r
-    return false;\r
-}\r
-\r
-gchar *\r
-ScalarParam::param_writeSVGValue() const\r
-{\r
-    Inkscape::SVGOStringStream os;\r
-    os << value;\r
-    gchar * str = g_strdup(os.str().c_str());\r
-    return str;\r
-}\r
-\r
-void\r
-ScalarParam::param_set_default() \r
-{\r
-    param_set_value(defvalue);\r
-}\r
-\r
-void\r
-ScalarParam::param_set_value(gdouble val) \r
-{\r
-    value = val;\r
-    if (integer)\r
-        value = round(value);\r
-    if (value > max)\r
-        value = max;\r
-    if (value < min)\r
-        value = min;\r
-\r
-    if (rsu && !rsu->is_updating())\r
-        rsu->setValue(value);\r
-}\r
-\r
-void\r
-ScalarParam::param_set_range(gdouble min, gdouble max) \r
-{\r
-    this->min = min;\r
-    this->max = max;\r
-    if (rsu)\r
-        rsu->getS()->setRange(min, max);\r
-\r
-    param_set_value(value); // reset value to see whether it is in ranges\r
-}\r
-\r
-void\r
-ScalarParam::param_make_integer(bool yes)\r
-{\r
-    integer = yes;\r
-    digits = 0;\r
-    inc_step = 1;\r
-    inc_page = 10;\r
-    if (rsu) {\r
-        rsu->getS()->setDigits(digits);\r
-        rsu->getS()->setIncrements(inc_step, inc_page);\r
-    }\r
-}\r
-\r
-Gtk::Widget *\r
-ScalarParam::param_getWidget()\r
-{\r
-    if (!rsu) {\r
-        rsu = new Inkscape::UI::Widget::RegisteredScalar();\r
-        rsu->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());\r
-        rsu->setValue(value);\r
-        rsu->getS()->setDigits(digits);\r
-        rsu->getS()->setIncrements(inc_step, inc_page);\r
-\r
-        rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter"));\r
-    }\r
-    return dynamic_cast<Gtk::Widget *> (rsu->getS());\r
-}\r
-\r
-void\r
-ScalarParam::param_set_digits(unsigned digits)\r
-{\r
-    this->digits = digits;\r
-    if (rsu) {\r
-        rsu->getS()->setDigits(digits);\r
-    }\r
-}\r
-\r
-void\r
-ScalarParam::param_set_increments(double step, double page)\r
-{\r
-    inc_step = step;\r
-    inc_page = page;\r
-    if (rsu) {\r
-        rsu->getS()->setIncrements(inc_step, inc_page);\r
-    }\r
-}\r
-\r
-\r
-\r
-\r
-} /* namespace LivePathEffect */\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/parameter.h"
+#include "live_effects/effect.h"
+#include "svg/svg.h"
+#include "libnr/nr-values.h"
+
+#include <gtkmm.h>
+#include "ui/widget/scalar.h"
+
+#include "svg/stringstream.h"
+
+#include "verbs.h"
+
+#define noLPEREALPARAM_DEBUG
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+
+Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip,
+                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+                      Effect* effect )
+{
+    param_label = label;
+    param_tooltip = tip;
+    param_key = key;
+    param_wr = wr;
+    param_effect = effect;
+}
+
+
+
+/*###########################################
+ *   REAL PARAM
+ */
+ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip,
+                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+                      Effect* effect, gdouble default_value)
+    : Parameter(label, tip, key, wr, effect)
+{
+    defvalue = default_value;
+    value = defvalue;
+    min = -NR_HUGE;
+    max = NR_HUGE;
+    integer = false;
+    rsu = NULL;
+    inc_step = 0.1;
+    inc_page = 1;
+    digits = 2;
+}
+
+ScalarParam::~ScalarParam()
+{
+    if (rsu)
+        delete rsu;
+}
+
+bool
+ScalarParam::param_readSVGValue(const gchar * strvalue)
+{
+    double newval;
+    unsigned int success = sp_svg_number_read_d(strvalue, &newval);
+    if (success == 1) {
+        param_set_value(newval);
+        return true;
+    }
+    return false;
+}
+
+gchar *
+ScalarParam::param_writeSVGValue() const
+{
+    Inkscape::SVGOStringStream os;
+    os << value;
+    gchar * str = g_strdup(os.str().c_str());
+    return str;
+}
+
+void
+ScalarParam::param_set_default() 
+{
+    param_set_value(defvalue);
+}
+
+void
+ScalarParam::param_set_value(gdouble val) 
+{
+    value = val;
+    if (integer)
+        value = round(value);
+    if (value > max)
+        value = max;
+    if (value < min)
+        value = min;
+
+    if (rsu && !rsu->is_updating())
+        rsu->setValue(value);
+}
+
+void
+ScalarParam::param_set_range(gdouble min, gdouble max) 
+{
+    this->min = min;
+    this->max = max;
+    if (rsu)
+        rsu->getS()->setRange(min, max);
+
+    param_set_value(value); // reset value to see whether it is in ranges
+}
+
+void
+ScalarParam::param_make_integer(bool yes)
+{
+    integer = yes;
+    digits = 0;
+    inc_step = 1;
+    inc_page = 10;
+    if (rsu) {
+        rsu->getS()->setDigits(digits);
+        rsu->getS()->setIncrements(inc_step, inc_page);
+    }
+}
+
+Gtk::Widget *
+ScalarParam::param_getWidget()
+{
+    if (!rsu) {
+        rsu = new Inkscape::UI::Widget::RegisteredScalar();
+        rsu->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());
+        rsu->setValue(value);
+        rsu->getS()->setDigits(digits);
+        rsu->getS()->setIncrements(inc_step, inc_page);
+
+        rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter"));
+    }
+    return dynamic_cast<Gtk::Widget *> (rsu->getS());
+}
+
+void
+ScalarParam::param_set_digits(unsigned digits)
+{
+    this->digits = digits;
+    if (rsu) {
+        rsu->getS()->setDigits(digits);
+    }
+}
+
+void
+ScalarParam::param_set_increments(double step, double page)
+{
+    inc_step = step;
+    inc_page = page;
+    if (rsu) {
+        rsu->getS()->setIncrements(inc_step, inc_page);
+    }
+}
+
+
+
+
+} /* namespace LivePathEffect */
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index fb0bb71036067ed6d9450fe4127364a70fa80104..a6b05bf362ad8185393ba4650b5ac42f7ecbc5ba 100644 (file)
-#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_H\r
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_H\r
-\r
-/*\r
- * Inkscape::LivePathEffectParameters\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <glibmm/ustring.h>\r
-#include <2geom/point.h>\r
-#include <2geom/path.h>\r
-\r
-#include "ui/widget/registry.h"\r
-#include "ui/widget/registered-widget.h"\r
-\r
-namespace Gtk {\r
-    class Widget;\r
-}\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-class Effect;\r
-\r
-class Parameter {\r
-public:\r
-    Parameter(  const Glib::ustring& label,\r
-                const Glib::ustring& tip,\r
-                const Glib::ustring& key,\r
-                Inkscape::UI::Widget::Registry* wr,\r
-                Effect* effect);\r
-    virtual ~Parameter() {};\r
-\r
-    virtual bool param_readSVGValue(const gchar * strvalue) = 0;   // returns true if new value is valid / accepted.\r
-    virtual gchar * param_writeSVGValue() const = 0;\r
-\r
-    virtual void param_set_default() = 0;\r
-\r
-    // This returns pointer to the parameter's widget to be put in the live-effects dialog. Must also create the\r
-    // necessary widget if it does not exist yet.\r
-    virtual Gtk::Widget * param_getWidget() = 0;\r
-    virtual Glib::ustring * param_getTooltip() { return &param_tooltip; };\r
-\r
-    Glib::ustring param_key;\r
-    Inkscape::UI::Widget::Registry * param_wr;\r
-    Glib::ustring param_label;\r
-\r
-protected:\r
-    Glib::ustring param_tooltip;\r
-\r
-    Effect* param_effect;\r
-\r
-private:\r
-    Parameter(const Parameter&);\r
-    Parameter& operator=(const Parameter&);\r
-};\r
-\r
-\r
-class ScalarParam : public Parameter {\r
-public:\r
-    ScalarParam(  const Glib::ustring& label,\r
-                const Glib::ustring& tip,\r
-                const Glib::ustring& key, \r
-                Inkscape::UI::Widget::Registry* wr,\r
-                Effect* effect,\r
-                gdouble default_value = 1.0);\r
-    virtual ~ScalarParam();\r
-\r
-    virtual bool param_readSVGValue(const gchar * strvalue);\r
-    virtual gchar * param_writeSVGValue() const;\r
-\r
-    virtual void param_set_default();\r
-    void param_set_value(gdouble val);\r
-    void param_make_integer(bool yes = true);\r
-    void param_set_range(gdouble min, gdouble max);\r
-    void param_set_digits(unsigned digits);\r
-    void param_set_increments(double step, double page);\r
-\r
-    virtual Gtk::Widget * param_getWidget();\r
-\r
-    inline operator gdouble()\r
-        { return value; };\r
-\r
-protected:\r
-    gdouble value;\r
-    gdouble min;\r
-    gdouble max;\r
-    bool integer;\r
-    gdouble defvalue;\r
-    Inkscape::UI::Widget::RegisteredScalar * rsu;\r
-    unsigned digits;\r
-    double inc_step;\r
-    double inc_page;\r
-\r
-private:\r
-    ScalarParam(const ScalarParam&);\r
-    ScalarParam& operator=(const ScalarParam&);\r
-};\r
-\r
-} //namespace LivePathEffect\r
-\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glibmm/ustring.h>
+#include <2geom/point.h>
+#include <2geom/path.h>
+
+#include "ui/widget/registry.h"
+#include "ui/widget/registered-widget.h"
+
+namespace Gtk {
+    class Widget;
+}
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+class Effect;
+
+class Parameter {
+public:
+    Parameter(  const Glib::ustring& label,
+                const Glib::ustring& tip,
+                const Glib::ustring& key,
+                Inkscape::UI::Widget::Registry* wr,
+                Effect* effect);
+    virtual ~Parameter() {};
+
+    virtual bool param_readSVGValue(const gchar * strvalue) = 0;   // returns true if new value is valid / accepted.
+    virtual gchar * param_writeSVGValue() const = 0;
+
+    virtual void param_set_default() = 0;
+
+    // This returns pointer to the parameter's widget to be put in the live-effects dialog. Must also create the
+    // necessary widget if it does not exist yet.
+    virtual Gtk::Widget * param_getWidget() = 0;
+    virtual Glib::ustring * param_getTooltip() { return &param_tooltip; };
+
+    Glib::ustring param_key;
+    Inkscape::UI::Widget::Registry * param_wr;
+    Glib::ustring param_label;
+
+protected:
+    Glib::ustring param_tooltip;
+
+    Effect* param_effect;
+
+private:
+    Parameter(const Parameter&);
+    Parameter& operator=(const Parameter&);
+};
+
+
+class ScalarParam : public Parameter {
+public:
+    ScalarParam(  const Glib::ustring& label,
+                const Glib::ustring& tip,
+                const Glib::ustring& key, 
+                Inkscape::UI::Widget::Registry* wr,
+                Effect* effect,
+                gdouble default_value = 1.0);
+    virtual ~ScalarParam();
+
+    virtual bool param_readSVGValue(const gchar * strvalue);
+    virtual gchar * param_writeSVGValue() const;
+
+    virtual void param_set_default();
+    void param_set_value(gdouble val);
+    void param_make_integer(bool yes = true);
+    void param_set_range(gdouble min, gdouble max);
+    void param_set_digits(unsigned digits);
+    void param_set_increments(double step, double page);
+
+    virtual Gtk::Widget * param_getWidget();
+
+    inline operator gdouble()
+        { return value; };
+
+protected:
+    gdouble value;
+    gdouble min;
+    gdouble max;
+    bool integer;
+    gdouble defvalue;
+    Inkscape::UI::Widget::RegisteredScalar * rsu;
+    unsigned digits;
+    double inc_step;
+    double inc_page;
+
+private:
+    ScalarParam(const ScalarParam&);
+    ScalarParam& operator=(const ScalarParam&);
+};
+
+} //namespace LivePathEffect
+
+} //namespace Inkscape
+
+#endif
index 4c73f0aeec18f7a9cc7703a6de6acba8bf8ed8c0..ff596bfc6dde589f5fa68d8000e1d164d315d93c 100644 (file)
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_PATH_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/parameter/path.h"\r
-#include "live_effects/effect.h"\r
-#include "live_effects/n-art-bpath-2geom.h"\r
-#include "svg/svg.h"\r
-#include <2geom/svg-path-parser.h>\r
-#include <2geom/sbasis-to-bezier.h>\r
-#include <2geom/d2.h>\r
-\r
-#include "ui/widget/point.h"\r
-#include "widgets/icon.h"\r
-#include <gtk/gtkstock.h>\r
-#include "selection-chemistry.h"\r
-\r
-#include "desktop.h"\r
-#include "inkscape.h"\r
-#include "message-stack.h"\r
-#include "verbs.h"\r
-#include "document.h"\r
-\r
-#define noLPEPATHPARAM_DEBUG\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-PathParam::PathParam( const Glib::ustring& label, const Glib::ustring& tip,\r
-                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
-                      Effect* effect, const gchar * default_value)\r
-    : Parameter(label, tip, key, wr, effect)\r
-{\r
-    _widget = NULL;\r
-    _tooltips = NULL;\r
-    defvalue = g_strdup(default_value);\r
-    param_readSVGValue(defvalue);\r
-}\r
-\r
-PathParam::~PathParam()\r
-{\r
-    if (_tooltips)\r
-        delete _tooltips;\r
-    // _widget is managed by GTK so do not delete!\r
-\r
-    g_free(defvalue);\r
-}\r
-\r
-void\r
-PathParam::param_set_default()\r
-{\r
-    param_readSVGValue(defvalue);\r
-}\r
-\r
-bool\r
-PathParam::param_readSVGValue(const gchar * strvalue)\r
-{\r
-    if (strvalue) {\r
-        Geom::Piecewise<Geom::D2<Geom::SBasis> > newpath;\r
-        std::vector<Geom::Path> temppath = SVGD_to_2GeomPath(strvalue);\r
-        for (unsigned int i=0; i < temppath.size(); i++) {\r
-            newpath.concat( temppath[i].toPwSb() );\r
-        }\r
-        *( dynamic_cast<Geom::Piecewise<Geom::D2<Geom::SBasis> > *> (this) ) = newpath;\r
-        signal_path_changed.emit();\r
-        return true;\r
-    }\r
-\r
-    return false;\r
-}\r
-\r
-gchar *\r
-PathParam::param_writeSVGValue() const\r
-{\r
-    const std::vector<Geom::Path> temppath =\r
-        Geom::path_from_piecewise(* dynamic_cast<const Geom::Piecewise<Geom::D2<Geom::SBasis> > *> (this), LPE_CONVERSION_TOLERANCE);\r
-    gchar * svgd = SVGD_from_2GeomPath( temppath );\r
-    return svgd;\r
-}\r
-\r
-Gtk::Widget *\r
-PathParam::param_getWidget()\r
-{\r
-    if (!_widget) {\r
-        _widget = Gtk::manage(new Gtk::HBox());\r
-        _tooltips = new Gtk::Tooltips();\r
-\r
-        Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label));\r
-        static_cast<Gtk::HBox*>(_widget)->pack_start(*pLabel, true, true);\r
-        _tooltips->set_tip(*pLabel, param_tooltip);\r
-\r
-        Gtk::Widget*  pIcon = Gtk::manage( sp_icon_get_icon( "draw_node", Inkscape::ICON_SIZE_BUTTON) );\r
-        Gtk::Button * pButton = Gtk::manage(new Gtk::Button());\r
-        pButton->set_relief(Gtk::RELIEF_NONE);\r
-        pIcon->show();\r
-        pButton->add(*pIcon);\r
-        pButton->show();\r
-        pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click));\r
-        static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);\r
-        _tooltips->set_tip(*pButton, _("Edit on-canvas"));\r
-#ifndef LPEPATHPARAM_DEBUG\r
-        pButton->set_sensitive(false);\r
-#endif\r
-\r
-        pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_PASTE, Inkscape::ICON_SIZE_BUTTON) );\r
-        pButton = Gtk::manage(new Gtk::Button());\r
-        pButton->set_relief(Gtk::RELIEF_NONE);\r
-        pIcon->show();\r
-        pButton->add(*pIcon);\r
-        pButton->show();\r
-        pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_paste_button_click));\r
-        static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);\r
-        _tooltips->set_tip(*pButton, _("Paste path"));\r
-\r
-        static_cast<Gtk::HBox*>(_widget)->show_all_children();\r
-\r
-    }\r
-    return dynamic_cast<Gtk::Widget *> (_widget);\r
-}\r
-\r
-void\r
-PathParam::on_edit_button_click()\r
-{\r
-    g_message("give this path to edit on canvas!");\r
-}\r
-\r
-void\r
-PathParam::on_paste_button_click()\r
-{\r
-    // check if something is in the clipboard\r
-    GSList * clipboard = sp_selection_get_clipboard();\r
-    if (clipboard == NULL || clipboard->data == NULL) {\r
-        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard."));\r
-        return;\r
-    }\r
-\r
-    Inkscape::XML::Node *repr = (Inkscape::XML::Node *) clipboard->data;\r
-    if (!strcmp (repr->name(), "svg:path")) {\r
-        const char * svgd = repr->attribute("d");\r
-        if (svgd) {\r
-            if (strchr(svgd,'A')) { // FIXME: temporary hack until 2Geom supports arcs in SVGD\r
-                SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE,\r
-                            _("This effect does not support arcs yet, try to convert to path.") );\r
-            } else {\r
-                param_write_to_repr(svgd);\r
-                signal_path_pasted.emit();\r
-                sp_document_done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, \r
-                                 _("Paste path parameter"));\r
-            }\r
-        }\r
-    } else {\r
-        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Clipboard does not contain a path."));\r
-    }\r
-\r
-}\r
-\r
-void\r
-PathParam::param_write_to_repr(const char * svgd)\r
-{\r
-    param_effect->getRepr()->setAttribute(param_key.c_str(), svgd);\r
-}\r
-\r
-\r
-} /* namespace LivePathEffect */\r
-\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_PATH_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/path.h"
+#include "live_effects/effect.h"
+#include "live_effects/n-art-bpath-2geom.h"
+#include "svg/svg.h"
+#include <2geom/svg-path-parser.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
+
+#include "ui/widget/point.h"
+#include "widgets/icon.h"
+#include <gtk/gtkstock.h>
+#include "selection-chemistry.h"
+
+#include "desktop.h"
+#include "inkscape.h"
+#include "message-stack.h"
+#include "verbs.h"
+#include "document.h"
+
+#define noLPEPATHPARAM_DEBUG
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+PathParam::PathParam( const Glib::ustring& label, const Glib::ustring& tip,
+                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+                      Effect* effect, const gchar * default_value)
+    : Parameter(label, tip, key, wr, effect)
+{
+    _widget = NULL;
+    _tooltips = NULL;
+    defvalue = g_strdup(default_value);
+    param_readSVGValue(defvalue);
+}
+
+PathParam::~PathParam()
+{
+    if (_tooltips)
+        delete _tooltips;
+    // _widget is managed by GTK so do not delete!
+
+    g_free(defvalue);
+}
+
+void
+PathParam::param_set_default()
+{
+    param_readSVGValue(defvalue);
+}
+
+bool
+PathParam::param_readSVGValue(const gchar * strvalue)
+{
+    if (strvalue) {
+        Geom::Piecewise<Geom::D2<Geom::SBasis> > newpath;
+        std::vector<Geom::Path> temppath = SVGD_to_2GeomPath(strvalue);
+        for (unsigned int i=0; i < temppath.size(); i++) {
+            newpath.concat( temppath[i].toPwSb() );
+        }
+        *( dynamic_cast<Geom::Piecewise<Geom::D2<Geom::SBasis> > *> (this) ) = newpath;
+        signal_path_changed.emit();
+        return true;
+    }
+
+    return false;
+}
+
+gchar *
+PathParam::param_writeSVGValue() const
+{
+    const std::vector<Geom::Path> temppath =
+        Geom::path_from_piecewise(* dynamic_cast<const Geom::Piecewise<Geom::D2<Geom::SBasis> > *> (this), LPE_CONVERSION_TOLERANCE);
+    gchar * svgd = SVGD_from_2GeomPath( temppath );
+    return svgd;
+}
+
+Gtk::Widget *
+PathParam::param_getWidget()
+{
+    if (!_widget) {
+        _widget = Gtk::manage(new Gtk::HBox());
+        _tooltips = new Gtk::Tooltips();
+
+        Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label));
+        static_cast<Gtk::HBox*>(_widget)->pack_start(*pLabel, true, true);
+        _tooltips->set_tip(*pLabel, param_tooltip);
+
+        Gtk::Widget*  pIcon = Gtk::manage( sp_icon_get_icon( "draw_node", Inkscape::ICON_SIZE_BUTTON) );
+        Gtk::Button * pButton = Gtk::manage(new Gtk::Button());
+        pButton->set_relief(Gtk::RELIEF_NONE);
+        pIcon->show();
+        pButton->add(*pIcon);
+        pButton->show();
+        pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click));
+        static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);
+        _tooltips->set_tip(*pButton, _("Edit on-canvas"));
+#ifndef LPEPATHPARAM_DEBUG
+        pButton->set_sensitive(false);
+#endif
+
+        pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_PASTE, Inkscape::ICON_SIZE_BUTTON) );
+        pButton = Gtk::manage(new Gtk::Button());
+        pButton->set_relief(Gtk::RELIEF_NONE);
+        pIcon->show();
+        pButton->add(*pIcon);
+        pButton->show();
+        pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_paste_button_click));
+        static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);
+        _tooltips->set_tip(*pButton, _("Paste path"));
+
+        static_cast<Gtk::HBox*>(_widget)->show_all_children();
+
+    }
+    return dynamic_cast<Gtk::Widget *> (_widget);
+}
+
+void
+PathParam::on_edit_button_click()
+{
+    g_message("give this path to edit on canvas!");
+}
+
+void
+PathParam::on_paste_button_click()
+{
+    // check if something is in the clipboard
+    GSList * clipboard = sp_selection_get_clipboard();
+    if (clipboard == NULL || clipboard->data == NULL) {
+        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard."));
+        return;
+    }
+
+    Inkscape::XML::Node *repr = (Inkscape::XML::Node *) clipboard->data;
+    if (!strcmp (repr->name(), "svg:path")) {
+        const char * svgd = repr->attribute("d");
+        if (svgd) {
+            if (strchr(svgd,'A')) { // FIXME: temporary hack until 2Geom supports arcs in SVGD
+                SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE,
+                            _("This effect does not support arcs yet, try to convert to path.") );
+            } else {
+                param_write_to_repr(svgd);
+                signal_path_pasted.emit();
+                sp_document_done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
+                                 _("Paste path parameter"));
+            }
+        }
+    } else {
+        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Clipboard does not contain a path."));
+    }
+
+}
+
+void
+PathParam::param_write_to_repr(const char * svgd)
+{
+    param_effect->getRepr()->setAttribute(param_key.c_str(), svgd);
+}
+
+
+} /* namespace LivePathEffect */
+
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index e26611b859da8ab8d0a2b7390b2aebd3dd895258..e966b7ebdb56a0dc66b301458f7ece1bf0a675c4 100644 (file)
@@ -1,66 +1,66 @@
-#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_PATH_H\r
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_PATH_H\r
-\r
-/*\r
- * Inkscape::LivePathEffectParameters\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <glib/gtypes.h>\r
-#include <2geom/path.h>\r
-\r
-#include "ui/widget/registry.h"\r
-#include <gtkmm/tooltips.h>\r
-\r
-#include "live_effects/parameter/parameter.h"\r
-\r
-#include <sigc++/sigc++.h>\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-class PathParam : public Geom::Piecewise<Geom::D2<Geom::SBasis> >, public Parameter {\r
-public:\r
-    PathParam ( const Glib::ustring& label,\r
-                const Glib::ustring& tip,\r
-                const Glib::ustring& key,\r
-                Inkscape::UI::Widget::Registry* wr,\r
-                Effect* effect,\r
-                const gchar * default_value = "M0,0 L1,1");\r
-    ~PathParam();\r
-\r
-    Gtk::Widget * param_getWidget();\r
-\r
-    bool param_readSVGValue(const gchar * strvalue);\r
-    gchar * param_writeSVGValue() const;\r
-\r
-    void param_set_default();\r
-\r
-    sigc::signal <void> signal_path_pasted;\r
-    sigc::signal <void> signal_path_changed;\r
-\r
-private:\r
-    PathParam(const PathParam&);\r
-    PathParam& operator=(const PathParam&);\r
-\r
-    Gtk::Widget * _widget;\r
-    Gtk::Tooltips * _tooltips;\r
-\r
-    void param_write_to_repr(const char * svgd);\r
-\r
-    void on_edit_button_click();\r
-    void on_paste_button_click();\r
-\r
-    gchar * defvalue;\r
-};\r
-\r
-\r
-} //namespace LivePathEffect\r
-\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_PATH_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_PATH_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gtypes.h>
+#include <2geom/path.h>
+
+#include "ui/widget/registry.h"
+#include <gtkmm/tooltips.h>
+
+#include "live_effects/parameter/parameter.h"
+
+#include <sigc++/sigc++.h>
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+class PathParam : public Geom::Piecewise<Geom::D2<Geom::SBasis> >, public Parameter {
+public:
+    PathParam ( const Glib::ustring& label,
+                const Glib::ustring& tip,
+                const Glib::ustring& key,
+                Inkscape::UI::Widget::Registry* wr,
+                Effect* effect,
+                const gchar * default_value = "M0,0 L1,1");
+    ~PathParam();
+
+    Gtk::Widget * param_getWidget();
+
+    bool param_readSVGValue(const gchar * strvalue);
+    gchar * param_writeSVGValue() const;
+
+    void param_set_default();
+
+    sigc::signal <void> signal_path_pasted;
+    sigc::signal <void> signal_path_changed;
+
+private:
+    PathParam(const PathParam&);
+    PathParam& operator=(const PathParam&);
+
+    Gtk::Widget * _widget;
+    Gtk::Tooltips * _tooltips;
+
+    void param_write_to_repr(const char * svgd);
+
+    void on_edit_button_click();
+    void on_paste_button_click();
+
+    gchar * defvalue;
+};
+
+
+} //namespace LivePathEffect
+
+} //namespace Inkscape
+
+#endif
index 3c42dcbfecc8d85539fd00e656bae036e4aa87ce..caa81692fdeb6e57e5cff3be2052a7c649c5aac2 100644 (file)
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/parameter/point.h"\r
-#include "live_effects/effect.h"\r
-#include "svg/svg.h"\r
-#include "svg/stringstream.h"\r
-#include <gtkmm.h>\r
-#include "ui/widget/point.h"\r
-#include "widgets/icon.h"\r
-\r
-#include "knot.h"\r
-#include "inkscape.h"\r
-#include "verbs.h"\r
-\r
-#define noLPEPOINTPARAM_DEBUG\r
-\r
-#define PRM_KNOT_COLOR_NORMAL 0xffffff00\r
-#define PRM_KNOT_COLOR_SELECTED 0x0000ff00\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip,\r
-                        const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
-                        Effect* effect, Geom::Point default_value )\r
-    : Geom::Point(default_value), Parameter(label, tip, key, wr, effect), defvalue(default_value)\r
-{\r
-    _widget = NULL;\r
-    pointwdg = NULL;\r
-    knot = NULL;\r
-    _tooltips = NULL;\r
-}\r
-\r
-PointParam::~PointParam()\r
-{\r
-    if (pointwdg)\r
-        delete pointwdg;\r
-    if (_tooltips)\r
-        delete _tooltips;\r
-\r
-    if (knot)\r
-        g_object_unref (G_OBJECT (knot));\r
-}\r
-\r
-void\r
-PointParam::param_set_default()\r
-{\r
-    param_setValue(defvalue);\r
-}\r
-\r
-bool\r
-PointParam::param_readSVGValue(const gchar * strvalue)\r
-{\r
-    gchar ** strarray = g_strsplit(strvalue, ",", 2);\r
-    double newx, newy;\r
-    unsigned int success = sp_svg_number_read_d(strarray[0], &newx);\r
-    success += sp_svg_number_read_d(strarray[1], &newy);\r
-    g_strfreev (strarray);\r
-    if (success == 2) {\r
-        param_setValue( Geom::Point(newx, newy) );\r
-        return true;\r
-    }\r
-    return false;\r
-}\r
-\r
-gchar *\r
-PointParam::param_writeSVGValue() const\r
-{\r
-    Inkscape::SVGOStringStream os;\r
-    os << (*this)[0] << "," << (*this)[1];\r
-    gchar * str = g_strdup(os.str().c_str());\r
-    return str;\r
-}\r
-\r
-Gtk::Widget *\r
-PointParam::param_getWidget()\r
-{\r
-    if (!_widget) {\r
-        pointwdg = new Inkscape::UI::Widget::RegisteredPoint();\r
-        pointwdg->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());\r
-        pointwdg->setValue( (*this)[0], (*this)[1] );\r
-        pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));\r
-\r
-        Gtk::Widget*  pIcon = Gtk::manage( sp_icon_get_icon( "draw_node", Inkscape::ICON_SIZE_BUTTON) );\r
-        Gtk::Button * pButton = Gtk::manage(new Gtk::Button());\r
-        pButton->set_relief(Gtk::RELIEF_NONE);\r
-        pIcon->show();\r
-        pButton->add(*pIcon);\r
-        pButton->show();\r
-        pButton->signal_clicked().connect(sigc::mem_fun(*this, &PointParam::on_button_click));\r
-#ifndef LPEPOINTPARAM_DEBUG\r
-        pButton->set_sensitive(false);\r
-#endif\r
-\r
-        _widget = Gtk::manage( new Gtk::HBox() );\r
-        static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);\r
-        static_cast<Gtk::HBox*>(_widget)->pack_start(*(pointwdg->getPoint()), true, true);\r
-        static_cast<Gtk::HBox*>(_widget)->show_all_children();\r
-\r
-        _tooltips = new Gtk::Tooltips();\r
-        _tooltips->set_tip(*pButton, _("Edit on-canvas"));\r
-    }\r
-    return dynamic_cast<Gtk::Widget *> (_widget);\r
-}\r
-\r
-void\r
-PointParam::param_setValue(Geom::Point newpoint)\r
-{\r
-    *dynamic_cast<Geom::Point *>( this ) = newpoint;\r
-    if (pointwdg)\r
-        pointwdg->setValue(newpoint[0], newpoint[1]);\r
-}\r
-\r
-\r
-// CALLBACKS:\r
-\r
-void\r
-PointParam::on_button_click()\r
-{\r
-    g_message("add knot to canvas on correct location :S");\r
-\r
-    if (!knot) {\r
-        // create the knot\r
-        knot = sp_knot_new (SP_ACTIVE_DESKTOP, NULL);\r
-        knot->setMode(SP_KNOT_MODE_XOR);\r
-        knot->setFill(PRM_KNOT_COLOR_NORMAL, PRM_KNOT_COLOR_NORMAL, PRM_KNOT_COLOR_NORMAL);\r
-        knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff);\r
-        sp_knot_update_ctrl(knot);\r
-\r
-        // move knot to the given point\r
-        sp_knot_set_position (knot, &NR::Point((*this)[0], (*this)[1]), SP_KNOT_STATE_NORMAL);\r
-        sp_knot_show (knot);\r
-/*\r
-        // connect knot's signals\r
-        if ( (draggable)  // it can be NULL if a node in unsnapped (eg. focus point unsnapped from center)\r
-                           // luckily, midstops never snap to other nodes so are never unsnapped...\r
-             && ( (draggable->point_type == POINT_LG_MID)\r
-                  || (draggable->point_type == POINT_RG_MID1)\r
-                  || (draggable->point_type == POINT_RG_MID2) ) )\r
-        {\r
-            this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_midpoint_handler), this);\r
-        } else {\r
-            this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_handler), this);\r
-        }\r
-        g_signal_connect (G_OBJECT (this->knot), "clicked", G_CALLBACK (gr_knot_clicked_handler), this);\r
-        g_signal_connect (G_OBJECT (this->knot), "doubleclicked", G_CALLBACK (gr_knot_doubleclicked_handler), this);\r
-        g_signal_connect (G_OBJECT (this->knot), "grabbed", G_CALLBACK (gr_knot_grabbed_handler), this);\r
-        g_signal_connect (G_OBJECT (this->knot), "ungrabbed", G_CALLBACK (gr_knot_ungrabbed_handler), this);\r
-*/\r
-    }\r
-}\r
-\r
-} /* namespace LivePathEffect */\r
-\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/point.h"
+#include "live_effects/effect.h"
+#include "svg/svg.h"
+#include "svg/stringstream.h"
+#include <gtkmm.h>
+#include "ui/widget/point.h"
+#include "widgets/icon.h"
+
+#include "knot.h"
+#include "inkscape.h"
+#include "verbs.h"
+
+#define noLPEPOINTPARAM_DEBUG
+
+#define PRM_KNOT_COLOR_NORMAL 0xffffff00
+#define PRM_KNOT_COLOR_SELECTED 0x0000ff00
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip,
+                        const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+                        Effect* effect, Geom::Point default_value )
+    : Geom::Point(default_value), Parameter(label, tip, key, wr, effect), defvalue(default_value)
+{
+    _widget = NULL;
+    pointwdg = NULL;
+    knot = NULL;
+    _tooltips = NULL;
+}
+
+PointParam::~PointParam()
+{
+    if (pointwdg)
+        delete pointwdg;
+    if (_tooltips)
+        delete _tooltips;
+
+    if (knot)
+        g_object_unref (G_OBJECT (knot));
+}
+
+void
+PointParam::param_set_default()
+{
+    param_setValue(defvalue);
+}
+
+bool
+PointParam::param_readSVGValue(const gchar * strvalue)
+{
+    gchar ** strarray = g_strsplit(strvalue, ",", 2);
+    double newx, newy;
+    unsigned int success = sp_svg_number_read_d(strarray[0], &newx);
+    success += sp_svg_number_read_d(strarray[1], &newy);
+    g_strfreev (strarray);
+    if (success == 2) {
+        param_setValue( Geom::Point(newx, newy) );
+        return true;
+    }
+    return false;
+}
+
+gchar *
+PointParam::param_writeSVGValue() const
+{
+    Inkscape::SVGOStringStream os;
+    os << (*this)[0] << "," << (*this)[1];
+    gchar * str = g_strdup(os.str().c_str());
+    return str;
+}
+
+Gtk::Widget *
+PointParam::param_getWidget()
+{
+    if (!_widget) {
+        pointwdg = new Inkscape::UI::Widget::RegisteredPoint();
+        pointwdg->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());
+        pointwdg->setValue( (*this)[0], (*this)[1] );
+        pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));
+
+        Gtk::Widget*  pIcon = Gtk::manage( sp_icon_get_icon( "draw_node", Inkscape::ICON_SIZE_BUTTON) );
+        Gtk::Button * pButton = Gtk::manage(new Gtk::Button());
+        pButton->set_relief(Gtk::RELIEF_NONE);
+        pIcon->show();
+        pButton->add(*pIcon);
+        pButton->show();
+        pButton->signal_clicked().connect(sigc::mem_fun(*this, &PointParam::on_button_click));
+#ifndef LPEPOINTPARAM_DEBUG
+        pButton->set_sensitive(false);
+#endif
+
+        _widget = Gtk::manage( new Gtk::HBox() );
+        static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);
+        static_cast<Gtk::HBox*>(_widget)->pack_start(*(pointwdg->getPoint()), true, true);
+        static_cast<Gtk::HBox*>(_widget)->show_all_children();
+
+        _tooltips = new Gtk::Tooltips();
+        _tooltips->set_tip(*pButton, _("Edit on-canvas"));
+    }
+    return dynamic_cast<Gtk::Widget *> (_widget);
+}
+
+void
+PointParam::param_setValue(Geom::Point newpoint)
+{
+    *dynamic_cast<Geom::Point *>( this ) = newpoint;
+    if (pointwdg)
+        pointwdg->setValue(newpoint[0], newpoint[1]);
+}
+
+
+// CALLBACKS:
+
+void
+PointParam::on_button_click()
+{
+    g_message("add knot to canvas on correct location :S");
+
+    if (!knot) {
+        // create the knot
+        knot = sp_knot_new (SP_ACTIVE_DESKTOP, NULL);
+        knot->setMode(SP_KNOT_MODE_XOR);
+        knot->setFill(PRM_KNOT_COLOR_NORMAL, PRM_KNOT_COLOR_NORMAL, PRM_KNOT_COLOR_NORMAL);
+        knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff);
+        sp_knot_update_ctrl(knot);
+
+        // move knot to the given point
+        sp_knot_set_position (knot, &NR::Point((*this)[0], (*this)[1]), SP_KNOT_STATE_NORMAL);
+        sp_knot_show (knot);
+/*
+        // connect knot's signals
+        if ( (draggable)  // it can be NULL if a node in unsnapped (eg. focus point unsnapped from center)
+                           // luckily, midstops never snap to other nodes so are never unsnapped...
+             && ( (draggable->point_type == POINT_LG_MID)
+                  || (draggable->point_type == POINT_RG_MID1)
+                  || (draggable->point_type == POINT_RG_MID2) ) )
+        {
+            this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_midpoint_handler), this);
+        } else {
+            this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_handler), this);
+        }
+        g_signal_connect (G_OBJECT (this->knot), "clicked", G_CALLBACK (gr_knot_clicked_handler), this);
+        g_signal_connect (G_OBJECT (this->knot), "doubleclicked", G_CALLBACK (gr_knot_doubleclicked_handler), this);
+        g_signal_connect (G_OBJECT (this->knot), "grabbed", G_CALLBACK (gr_knot_grabbed_handler), this);
+        g_signal_connect (G_OBJECT (this->knot), "ungrabbed", G_CALLBACK (gr_knot_ungrabbed_handler), this);
+*/
+    }
+}
+
+} /* namespace LivePathEffect */
+
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index c1d6681a255df10e12e72272897165f0e0c07fe4..c3ed876f7e032d04fd414d52783cca163608183c 100644 (file)
@@ -1,65 +1,65 @@
-#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_H\r
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_H\r
-\r
-/*\r
- * Inkscape::LivePathEffectParameters\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include <glib/gtypes.h>\r
-#include <2geom/point.h>\r
-\r
-#include "ui/widget/registry.h"\r
-#include "ui/widget/registered-widget.h"\r
-#include <gtkmm/tooltips.h>\r
-\r
-#include "live_effects/parameter/parameter.h"\r
-\r
-struct SPKnot;\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-\r
-class PointParam : public Geom::Point, public Parameter {\r
-public:\r
-    PointParam( const Glib::ustring& label,\r
-                const Glib::ustring& tip,\r
-                const Glib::ustring& key,\r
-                Inkscape::UI::Widget::Registry* wr,\r
-                Effect* effect,\r
-                Geom::Point default_value = Geom::Point(0,0));\r
-    ~PointParam();\r
-\r
-    Gtk::Widget * param_getWidget();\r
-\r
-    bool param_readSVGValue(const gchar * strvalue);\r
-    gchar * param_writeSVGValue() const;\r
-\r
-    void param_setValue(Geom::Point newpoint);\r
-    void param_set_default();\r
-\r
-private:\r
-    PointParam(const PointParam&);\r
-    PointParam& operator=(const PointParam&);\r
-\r
-    Gtk::Widget * _widget;\r
-    Gtk::Tooltips * _tooltips;\r
-    Inkscape::UI::Widget::RegisteredPoint * pointwdg;\r
-    void on_button_click();\r
-\r
-    SPKnot *knot;\r
-\r
-    Geom::Point defvalue;\r
-};\r
-\r
-\r
-} //namespace LivePathEffect\r
-\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib/gtypes.h>
+#include <2geom/point.h>
+
+#include "ui/widget/registry.h"
+#include "ui/widget/registered-widget.h"
+#include <gtkmm/tooltips.h>
+
+#include "live_effects/parameter/parameter.h"
+
+struct SPKnot;
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+
+class PointParam : public Geom::Point, public Parameter {
+public:
+    PointParam( const Glib::ustring& label,
+                const Glib::ustring& tip,
+                const Glib::ustring& key,
+                Inkscape::UI::Widget::Registry* wr,
+                Effect* effect,
+                Geom::Point default_value = Geom::Point(0,0));
+    ~PointParam();
+
+    Gtk::Widget * param_getWidget();
+
+    bool param_readSVGValue(const gchar * strvalue);
+    gchar * param_writeSVGValue() const;
+
+    void param_setValue(Geom::Point newpoint);
+    void param_set_default();
+
+private:
+    PointParam(const PointParam&);
+    PointParam& operator=(const PointParam&);
+
+    Gtk::Widget * _widget;
+    Gtk::Tooltips * _tooltips;
+    Inkscape::UI::Widget::RegisteredPoint * pointwdg;
+    void on_button_click();
+
+    SPKnot *knot;
+
+    Geom::Point defvalue;
+};
+
+
+} //namespace LivePathEffect
+
+} //namespace Inkscape
+
+#endif
index 846c2f9e8de17761f284765da903fc12c0329d7a..959b21114a3713493fd1bb8680ae8d31eb6bb920 100644 (file)
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_CPP\r
-\r
-/*\r
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/parameter/random.h"\r
-#include "live_effects/effect.h"\r
-#include "svg/svg.h"\r
-#include "libnr/nr-values.h"\r
-\r
-#include <gtkmm.h>\r
-#include "ui/widget/random.h"\r
-\r
-#include "svg/stringstream.h"\r
-\r
-#include "verbs.h"\r
-\r
-#define noLPERANDOMPARAM_DEBUG\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-\r
-RandomParam::RandomParam( const Glib::ustring& label, const Glib::ustring& tip,\r
-                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,\r
-                      Effect* effect, gdouble default_value, long default_seed)\r
-    : Parameter(label, tip, key, wr, effect)\r
-{\r
-    defvalue = default_value;\r
-    value = defvalue;\r
-    min = -NR_HUGE;\r
-    max = NR_HUGE;\r
-    integer = false;\r
-    regrandom = NULL;\r
-\r
-    defseed = default_seed;\r
-    startseed = defseed;\r
-    seed = startseed;\r
-}\r
-\r
-RandomParam::~RandomParam()\r
-{\r
-    if (regrandom)\r
-        delete regrandom;\r
-}\r
-\r
-bool\r
-RandomParam::param_readSVGValue(const gchar * strvalue)\r
-{\r
-    double newval, newstartseed;\r
-    gchar** stringarray = g_strsplit (strvalue, ";", 2);\r
-    unsigned int success = sp_svg_number_read_d(stringarray[0], &newval);\r
-    if (success == 1) {\r
-        success += sp_svg_number_read_d(stringarray[1], &newstartseed);\r
-        if (success == 2) {\r
-            param_set_value(newval, newstartseed);\r
-        } else {\r
-            param_set_value(newval, defseed);\r
-        }\r
-        g_strfreev(stringarray);\r
-        return true;\r
-    }\r
-    g_strfreev(stringarray);\r
-    return false;\r
-}\r
-\r
-gchar *\r
-RandomParam::param_writeSVGValue() const\r
-{\r
-    Inkscape::SVGOStringStream os;\r
-    os << value << ';' << startseed;\r
-    gchar * str = g_strdup(os.str().c_str());\r
-    return str;\r
-}\r
-\r
-void\r
-RandomParam::param_set_default() \r
-{\r
-    param_set_value(defvalue, defseed);\r
-}\r
-\r
-void\r
-RandomParam::param_set_value(gdouble val, long newseed) \r
-{\r
-    value = val;\r
-    if (integer)\r
-        value = round(value);\r
-    if (value > max)\r
-        value = max;\r
-    if (value < min)\r
-        value = min;\r
-\r
-    startseed = setup_seed(newseed);\r
-    seed = startseed;\r
-\r
-    if (regrandom)\r
-        regrandom->setValue(value, startseed);\r
-}\r
-\r
-void\r
-RandomParam::param_set_range(gdouble min, gdouble max) \r
-{\r
-    this->min = min;\r
-    this->max = max;\r
-    if (regrandom)\r
-        regrandom->getR()->setRange(min, max);\r
-\r
-    param_set_value(value, startseed); // reset value, to check whether it is in range\r
-}\r
-\r
-void\r
-RandomParam::param_make_integer(bool yes)\r
-{\r
-    integer = yes;\r
-    if (regrandom) {\r
-        regrandom->getR()->setDigits(0);\r
-        regrandom->getR()->setIncrements(1, 10);\r
-    }\r
-}\r
-\r
-void\r
-RandomParam::resetRandomizer()\r
-{\r
-    seed = startseed;\r
-}\r
-\r
-\r
-Gtk::Widget *\r
-RandomParam::param_getWidget()\r
-{\r
-    // TODO: add  a button to set a different startseed\r
-    if (!regrandom) {\r
-        regrandom = new Inkscape::UI::Widget::RegisteredRandom();\r
-        regrandom->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());\r
-        regrandom->setValue(value, startseed);\r
-        if (integer)\r
-            param_make_integer();\r
-\r
-        regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter"));\r
-    }\r
-    return dynamic_cast<Gtk::Widget *> (regrandom->getR());\r
-}\r
-\r
-RandomParam::operator gdouble()\r
-{\r
-    return rand() * value;\r
-};\r
-\r
-/* RNG stolen from /display/nr-filter-turbulence.cpp */\r
-#define RAND_m 2147483647 /* 2**31 - 1 */\r
-#define RAND_a 16807 /* 7**5; primitive root of m */\r
-#define RAND_q 127773 /* m / a */\r
-#define RAND_r 2836 /* m % a */\r
-#define BSize 0x100\r
-\r
-long\r
-RandomParam::setup_seed(long lSeed)\r
-{\r
-  if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;\r
-  if (lSeed > RAND_m - 1) lSeed = RAND_m - 1;\r
-  return lSeed;\r
-}\r
-\r
-// generates random number between 0 and 1\r
-gdouble\r
-RandomParam::rand()\r
-{\r
-  long result;\r
-  result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q);\r
-  if (result <= 0) result += RAND_m;\r
-  seed = result;\r
-\r
-  gdouble dresult = (gdouble)(result % BSize) / BSize;\r
-  return dresult;\r
-}\r
-\r
-\r
-} /* namespace LivePathEffect */\r
-} /* namespace Inkscape */\r
-\r
-/*\r
-  Local Variables:\r
-  mode:c++\r
-  c-file-style:"stroustrup"\r
-  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
-  indent-tabs-mode:nil\r
-  fill-column:99\r
-  End:\r
-*/\r
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_CPP
+
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/random.h"
+#include "live_effects/effect.h"
+#include "svg/svg.h"
+#include "libnr/nr-values.h"
+
+#include <gtkmm.h>
+#include "ui/widget/random.h"
+
+#include "svg/stringstream.h"
+
+#include "verbs.h"
+
+#define noLPERANDOMPARAM_DEBUG
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+
+RandomParam::RandomParam( const Glib::ustring& label, const Glib::ustring& tip,
+                      const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+                      Effect* effect, gdouble default_value, long default_seed)
+    : Parameter(label, tip, key, wr, effect)
+{
+    defvalue = default_value;
+    value = defvalue;
+    min = -NR_HUGE;
+    max = NR_HUGE;
+    integer = false;
+    regrandom = NULL;
+
+    defseed = default_seed;
+    startseed = defseed;
+    seed = startseed;
+}
+
+RandomParam::~RandomParam()
+{
+    if (regrandom)
+        delete regrandom;
+}
+
+bool
+RandomParam::param_readSVGValue(const gchar * strvalue)
+{
+    double newval, newstartseed;
+    gchar** stringarray = g_strsplit (strvalue, ";", 2);
+    unsigned int success = sp_svg_number_read_d(stringarray[0], &newval);
+    if (success == 1) {
+        success += sp_svg_number_read_d(stringarray[1], &newstartseed);
+        if (success == 2) {
+            param_set_value(newval, newstartseed);
+        } else {
+            param_set_value(newval, defseed);
+        }
+        g_strfreev(stringarray);
+        return true;
+    }
+    g_strfreev(stringarray);
+    return false;
+}
+
+gchar *
+RandomParam::param_writeSVGValue() const
+{
+    Inkscape::SVGOStringStream os;
+    os << value << ';' << startseed;
+    gchar * str = g_strdup(os.str().c_str());
+    return str;
+}
+
+void
+RandomParam::param_set_default() 
+{
+    param_set_value(defvalue, defseed);
+}
+
+void
+RandomParam::param_set_value(gdouble val, long newseed) 
+{
+    value = val;
+    if (integer)
+        value = round(value);
+    if (value > max)
+        value = max;
+    if (value < min)
+        value = min;
+
+    startseed = setup_seed(newseed);
+    seed = startseed;
+
+    if (regrandom)
+        regrandom->setValue(value, startseed);
+}
+
+void
+RandomParam::param_set_range(gdouble min, gdouble max) 
+{
+    this->min = min;
+    this->max = max;
+    if (regrandom)
+        regrandom->getR()->setRange(min, max);
+
+    param_set_value(value, startseed); // reset value, to check whether it is in range
+}
+
+void
+RandomParam::param_make_integer(bool yes)
+{
+    integer = yes;
+    if (regrandom) {
+        regrandom->getR()->setDigits(0);
+        regrandom->getR()->setIncrements(1, 10);
+    }
+}
+
+void
+RandomParam::resetRandomizer()
+{
+    seed = startseed;
+}
+
+
+Gtk::Widget *
+RandomParam::param_getWidget()
+{
+    // TODO: add  a button to set a different startseed
+    if (!regrandom) {
+        regrandom = new Inkscape::UI::Widget::RegisteredRandom();
+        regrandom->init(param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc());
+        regrandom->setValue(value, startseed);
+        if (integer)
+            param_make_integer();
+
+        regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter"));
+    }
+    return dynamic_cast<Gtk::Widget *> (regrandom->getR());
+}
+
+RandomParam::operator gdouble()
+{
+    return rand() * value;
+};
+
+/* RNG stolen from /display/nr-filter-turbulence.cpp */
+#define RAND_m 2147483647 /* 2**31 - 1 */
+#define RAND_a 16807 /* 7**5; primitive root of m */
+#define RAND_q 127773 /* m / a */
+#define RAND_r 2836 /* m % a */
+#define BSize 0x100
+
+long
+RandomParam::setup_seed(long lSeed)
+{
+  if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;
+  if (lSeed > RAND_m - 1) lSeed = RAND_m - 1;
+  return lSeed;
+}
+
+// generates random number between 0 and 1
+gdouble
+RandomParam::rand()
+{
+  long result;
+  result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q);
+  if (result <= 0) result += RAND_m;
+  seed = result;
+
+  gdouble dresult = (gdouble)(result % BSize) / BSize;
+  return dresult;
+}
+
+
+} /* namespace LivePathEffect */
+} /* namespace Inkscape */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 772f46ac68a3326f5964ba76cbdf2c715f3e06a6..55171c973131140628c6548990856cca5f003203 100644 (file)
@@ -1,76 +1,76 @@
-#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_H\r
-#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_H\r
-\r
-/*\r
- * Inkscape::LivePathEffectParameters\r
- *\r
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#include "live_effects/parameter/parameter.h"\r
-#include <glibmm/ustring.h>\r
-#include <2geom/point.h>\r
-#include <2geom/path.h>\r
-\r
-#include "ui/widget/registry.h"\r
-#include "ui/widget/registered-widget.h"\r
-\r
-namespace Inkscape {\r
-\r
-namespace LivePathEffect {\r
-\r
-class RandomParam : public Parameter {\r
-public:\r
-    RandomParam(  const Glib::ustring& label,\r
-                const Glib::ustring& tip,\r
-                const Glib::ustring& key, \r
-                Inkscape::UI::Widget::Registry* wr,\r
-                Effect* effect,\r
-                gdouble default_value = 1.0,\r
-                long default_seed = 0);\r
-    virtual ~RandomParam();\r
-\r
-    virtual bool param_readSVGValue(const gchar * strvalue);\r
-    virtual gchar * param_writeSVGValue() const;\r
-    virtual void param_set_default();\r
-\r
-    virtual Gtk::Widget * param_getWidget();\r
-\r
-    void param_set_value(gdouble val, long newseed);\r
-    void param_make_integer(bool yes = true);\r
-    void param_set_range(gdouble min, gdouble max);\r
-\r
-    void resetRandomizer();\r
-\r
-    operator gdouble();\r
-    inline gdouble get_value()\r
-        { return value; } ;\r
-\r
-protected:\r
-    long startseed;\r
-    long seed;\r
-    long defseed;\r
-\r
-    gdouble value;\r
-    gdouble min;\r
-    gdouble max;\r
-    bool integer;\r
-    gdouble defvalue;\r
-\r
-    Inkscape::UI::Widget::RegisteredRandom * regrandom;\r
-\r
-private:\r
-    long setup_seed(long);\r
-    gdouble rand();\r
-\r
-    RandomParam(const RandomParam&);\r
-    RandomParam& operator=(const RandomParam&);\r
-};\r
-\r
-} //namespace LivePathEffect\r
-\r
-} //namespace Inkscape\r
-\r
-#endif\r
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/parameter.h"
+#include <glibmm/ustring.h>
+#include <2geom/point.h>
+#include <2geom/path.h>
+
+#include "ui/widget/registry.h"
+#include "ui/widget/registered-widget.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+class RandomParam : public Parameter {
+public:
+    RandomParam(  const Glib::ustring& label,
+                const Glib::ustring& tip,
+                const Glib::ustring& key, 
+                Inkscape::UI::Widget::Registry* wr,
+                Effect* effect,
+                gdouble default_value = 1.0,
+                long default_seed = 0);
+    virtual ~RandomParam();
+
+    virtual bool param_readSVGValue(const gchar * strvalue);
+    virtual gchar * param_writeSVGValue() const;
+    virtual void param_set_default();
+
+    virtual Gtk::Widget * param_getWidget();
+
+    void param_set_value(gdouble val, long newseed);
+    void param_make_integer(bool yes = true);
+    void param_set_range(gdouble min, gdouble max);
+
+    void resetRandomizer();
+
+    operator gdouble();
+    inline gdouble get_value()
+        { return value; } ;
+
+protected:
+    long startseed;
+    long seed;
+    long defseed;
+
+    gdouble value;
+    gdouble min;
+    gdouble max;
+    bool integer;
+    gdouble defvalue;
+
+    Inkscape::UI::Widget::RegisteredRandom * regrandom;
+
+private:
+    long setup_seed(long);
+    gdouble rand();
+
+    RandomParam(const RandomParam&);
+    RandomParam& operator=(const RandomParam&);
+};
+
+} //namespace LivePathEffect
+
+} //namespace Inkscape
+
+#endif