1 #define INKSCAPE_LIVEPATHEFFECT_PARAMETER_RANDOM_CPP
3 /*
4 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
5 *
6 * Released under GNU GPL, read the file 'COPYING' for more information
7 */
9 #include "live_effects/parameter/random.h"
10 #include "live_effects/effect.h"
11 #include "svg/svg.h"
12 #include "libnr/nr-values.h"
14 #include <gtkmm.h>
15 #include "ui/widget/random.h"
17 #include "svg/stringstream.h"
19 #include "verbs.h"
21 #define noLPERANDOMPARAM_DEBUG
23 namespace Inkscape {
25 namespace LivePathEffect {
28 RandomParam::RandomParam( const Glib::ustring& label, const Glib::ustring& tip,
29 const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
30 Effect* effect, gdouble default_value, long default_seed)
31 : Parameter(label, tip, key, wr, effect)
32 {
33 defvalue = default_value;
34 value = defvalue;
35 min = -NR_HUGE;
36 max = NR_HUGE;
37 integer = false;
39 defseed = default_seed;
40 startseed = defseed;
41 seed = startseed;
42 }
44 RandomParam::~RandomParam()
45 {
46 }
48 bool
49 RandomParam::param_readSVGValue(const gchar * strvalue)
50 {
51 double newval, newstartseed;
52 gchar** stringarray = g_strsplit (strvalue, ";", 2);
53 unsigned int success = sp_svg_number_read_d(stringarray[0], &newval);
54 if (success == 1) {
55 success += sp_svg_number_read_d(stringarray[1], &newstartseed);
56 if (success == 2) {
57 param_set_value(newval, newstartseed);
58 } else {
59 param_set_value(newval, defseed);
60 }
61 g_strfreev(stringarray);
62 return true;
63 }
64 g_strfreev(stringarray);
65 return false;
66 }
68 gchar *
69 RandomParam::param_writeSVGValue() const
70 {
71 Inkscape::SVGOStringStream os;
72 os << value << ';' << startseed;
73 gchar * str = g_strdup(os.str().c_str());
74 return str;
75 }
77 void
78 RandomParam::param_set_default()
79 {
80 param_set_value(defvalue, defseed);
81 }
83 void
84 RandomParam::param_set_value(gdouble val, long newseed)
85 {
86 value = val;
87 if (integer)
88 value = round(value);
89 if (value > max)
90 value = max;
91 if (value < min)
92 value = min;
94 startseed = setup_seed(newseed);
95 seed = startseed;
96 }
98 void
99 RandomParam::param_set_range(gdouble min, gdouble max)
100 {
101 this->min = min;
102 this->max = max;
103 }
105 void
106 RandomParam::param_make_integer(bool yes)
107 {
108 integer = yes;
109 }
111 void
112 RandomParam::resetRandomizer()
113 {
114 seed = startseed;
115 }
118 Gtk::Widget *
119 RandomParam::param_newWidget(Gtk::Tooltips * /*tooltips*/)
120 {
121 Inkscape::UI::Widget::RegisteredRandom* regrandom = Gtk::manage(
122 new Inkscape::UI::Widget::RegisteredRandom( param_label,
123 param_tooltip,
124 param_key,
125 *param_wr,
126 param_effect->getRepr(),
127 param_effect->getSPDoc() ) );
129 regrandom->setValue(value, startseed);
130 if (integer) {
131 regrandom->setDigits(0);
132 regrandom->setIncrements(1, 10);
133 }
134 regrandom->setRange(min, max);
135 regrandom->setProgrammatically = false;
137 regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter"));
139 return dynamic_cast<Gtk::Widget *> (regrandom);
140 }
142 RandomParam::operator gdouble()
143 {
144 return rand() * value;
145 };
147 /* RNG stolen from /display/nr-filter-turbulence.cpp */
148 #define RAND_m 2147483647 /* 2**31 - 1 */
149 #define RAND_a 16807 /* 7**5; primitive root of m */
150 #define RAND_q 127773 /* m / a */
151 #define RAND_r 2836 /* m % a */
152 #define BSize 0x100
154 long
155 RandomParam::setup_seed(long lSeed)
156 {
157 if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;
158 if (lSeed > RAND_m - 1) lSeed = RAND_m - 1;
159 return lSeed;
160 }
162 // generates random number between 0 and 1
163 gdouble
164 RandomParam::rand()
165 {
166 long result;
167 result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q);
168 if (result <= 0) result += RAND_m;
169 seed = result;
171 gdouble dresult = (gdouble)(result % BSize) / BSize;
172 return dresult;
173 }
176 } /* namespace LivePathEffect */
177 } /* namespace Inkscape */
179 /*
180 Local Variables:
181 mode:c++
182 c-file-style:"stroustrup"
183 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
184 indent-tabs-mode:nil
185 fill-column:99
186 End:
187 */
188 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :