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);
136 regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter"));
138 return dynamic_cast<Gtk::Widget *> (regrandom);
139 }
141 RandomParam::operator gdouble()
142 {
143 return rand() * value;
144 };
146 /* RNG stolen from /display/nr-filter-turbulence.cpp */
147 #define RAND_m 2147483647 /* 2**31 - 1 */
148 #define RAND_a 16807 /* 7**5; primitive root of m */
149 #define RAND_q 127773 /* m / a */
150 #define RAND_r 2836 /* m % a */
151 #define BSize 0x100
153 long
154 RandomParam::setup_seed(long lSeed)
155 {
156 if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;
157 if (lSeed > RAND_m - 1) lSeed = RAND_m - 1;
158 return lSeed;
159 }
161 // generates random number between 0 and 1
162 gdouble
163 RandomParam::rand()
164 {
165 long result;
166 result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q);
167 if (result <= 0) result += RAND_m;
168 seed = result;
170 gdouble dresult = (gdouble)(result % BSize) / BSize;
171 return dresult;
172 }
175 } /* namespace LivePathEffect */
176 } /* namespace Inkscape */
178 /*
179 Local Variables:
180 mode:c++
181 c-file-style:"stroustrup"
182 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
183 indent-tabs-mode:nil
184 fill-column:99
185 End:
186 */
187 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :