diff options
Diffstat (limited to 'src/live_effects/parameter/random.cpp')
-rw-r--r-- | src/live_effects/parameter/random.cpp | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp new file mode 100644 index 0000000..42f5065 --- /dev/null +++ b/src/live_effects/parameter/random.cpp @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "random.h" + +#include <glibmm/i18n.h> + +#include "live_effects/effect.h" +#include "svg/stringstream.h" +#include "svg/svg.h" +#include "ui/icon-names.h" +#include "ui/widget/random.h" +#include "ui/widget/registered-widget.h" + +#define noLPERANDOMPARAM_DEBUG + +/* 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 + +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, bool randomsign) + : Parameter(label, tip, key, wr, effect) +{ + defvalue = default_value; + value = defvalue; + min = -Geom::infinity(); + max = Geom::infinity(); + integer = false; + + defseed = default_seed; + startseed = defseed; + seed = startseed; + _randomsign = randomsign; +} + +RandomParam::~RandomParam() += default; + +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, static_cast<long>(newstartseed)); + } else { + param_set_value(newval, defseed); + } + g_strfreev(stringarray); + return true; + } + g_strfreev(stringarray); + return false; +} + +Glib::ustring +RandomParam::param_getSVGValue() const +{ + Inkscape::SVGOStringStream os; + os << value << ';' << startseed; + return os.str(); +} + +Glib::ustring +RandomParam::param_getDefaultSVGValue() const +{ + Inkscape::SVGOStringStream os; + os << defvalue << ';' << defseed; + return os.str(); +} + +void +RandomParam::param_set_default() +{ + param_set_value(defvalue, defseed); +} + +void +RandomParam::param_update_default(gdouble default_value){ + defvalue = default_value; +} + +void +RandomParam::param_update_default(const gchar * default_value){ + double newval; + unsigned int success = sp_svg_number_read_d(default_value, &newval); + if (success == 1) { + param_update_default(newval); + } +} + +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); + // we reach maximum value so randomize over to fix duple in next cycle + Glib::ustring version = param_effect->lpeversion.param_getSVGValue(); + if (startseed == RAND_m - 1 && (( + effectType() != ROUGH_HATCHES && + effectType() != ROUGHEN) || + version >= "1.2")) + { + startseed = rand() * startseed; + } + seed = startseed; +} + +void +RandomParam::param_set_range(gdouble min, gdouble max) +{ + this->min = min; + this->max = max; +} + +void +RandomParam::param_make_integer(bool yes) +{ + integer = yes; +} + +void +RandomParam::resetRandomizer() +{ + seed = startseed; +} + + +Gtk::Widget * +RandomParam::param_newWidget() +{ + Inkscape::UI::Widget::RegisteredRandom* regrandom = Gtk::manage( + new Inkscape::UI::Widget::RegisteredRandom( param_label, + param_tooltip, + param_key, + *param_wr, + param_effect->getRepr(), + param_effect->getSPDoc() ) ); + + regrandom->setValue(value, startseed); + if (integer) { + regrandom->setDigits(0); + regrandom->setIncrements(1, 10); + } + regrandom->setRange(min, max); + regrandom->setProgrammatically = false; + regrandom->signal_button_release_event().connect(sigc::mem_fun (*this, &RandomParam::on_button_release)); + + regrandom->set_undo_parameters(_("Change random parameter"), INKSCAPE_ICON("dialog-path-effects")); + + return dynamic_cast<Gtk::Widget *> (regrandom); +} + +bool RandomParam::on_button_release(GdkEventButton* button_event) { + param_effect->refresh_widgets = true; + return false; +} + +RandomParam::operator gdouble() +{ + if (_randomsign) { + return (rand() * value) - (rand() * value); + } else { + return rand() * value; + } +}; + + +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 : |