// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) Johan Engelen 2007 * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include "random.h" #include #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(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 (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 :