~ubuntu-branches/ubuntu/natty/inkscape/natty

« back to all changes in this revision

Viewing changes to src/sp-star.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alex Valavanis
  • Date: 2010-09-12 19:44:58 UTC
  • mfrom: (1.1.12 upstream) (45.1.3 maverick)
  • Revision ID: james.westby@ubuntu.com-20100912194458-4sjwmbl7dlsrk5dc
Tags: 0.48.0-1ubuntu1
* Merge with Debian unstable (LP: #628048, LP: #401567, LP: #456248, 
  LP: #463602, LP: #591986)
* debian/control: 
  - Ubuntu maintainers
  - Promote python-lxml, python-numpy, python-uniconvertor to Recommends.
  - Demote pstoedit to Suggests (universe package).
  - Suggests ttf-dejavu instead of ttf-bitstream-vera (LP: #513319)
* debian/rules:
  - Run intltool-update on build (Ubuntu-specific).
  - Add translation domain to .desktop files (Ubuntu-specific).
* debian/dirs:
  - Add usr/share/pixmaps.  Allow inkscape.xpm installation
* drop 50-poppler-API.dpatch (now upstream)
* drop 51-paste-in-unwritable-directory.dpatch (now upstream) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
static void sp_star_update (SPObject *object, SPCtx *ctx, guint flags);
42
42
 
43
43
static gchar * sp_star_description (SPItem * item);
44
 
static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
44
static void sp_star_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
45
45
 
46
46
static void sp_star_set_shape (SPShape *shape);
47
47
static void sp_star_update_patheffect (SPLPEItem *lpeitem, bool write);
51
51
GType
52
52
sp_star_get_type (void)
53
53
{
54
 
        static GType type = 0;
 
54
    static GType type = 0;
55
55
 
56
 
        if (!type) {
57
 
                GTypeInfo info = {
58
 
                        sizeof (SPStarClass),
59
 
                        NULL, NULL,
60
 
                        (GClassInitFunc) sp_star_class_init,
61
 
                        NULL, NULL,
62
 
                        sizeof (SPStar),
63
 
                        16,
64
 
                        (GInstanceInitFunc) sp_star_init,
65
 
                        NULL,   /* value_table */
66
 
                };
67
 
                type = g_type_register_static (SP_TYPE_SHAPE, "SPStar", &info, (GTypeFlags)0);
68
 
        }
69
 
        return type;
 
56
    if (!type) {
 
57
        GTypeInfo info = {
 
58
            sizeof (SPStarClass),
 
59
            NULL, NULL,
 
60
            (GClassInitFunc) sp_star_class_init,
 
61
            NULL, NULL,
 
62
            sizeof (SPStar),
 
63
            16,
 
64
            (GInstanceInitFunc) sp_star_init,
 
65
            NULL,    /* value_table */
 
66
        };
 
67
        type = g_type_register_static (SP_TYPE_SHAPE, "SPStar", &info, (GTypeFlags)0);
 
68
    }
 
69
    return type;
70
70
}
71
71
 
72
72
static void
73
73
sp_star_class_init (SPStarClass *klass)
74
74
{
75
 
        GObjectClass * gobject_class;
76
 
        SPObjectClass * sp_object_class;
77
 
        SPItemClass * item_class;
78
 
        SPLPEItemClass * lpe_item_class;
79
 
        SPShapeClass * shape_class;
80
 
 
81
 
        gobject_class = (GObjectClass *) klass;
82
 
        sp_object_class = (SPObjectClass *) klass;
83
 
        item_class = (SPItemClass *) klass;
84
 
        lpe_item_class = (SPLPEItemClass *) klass;
85
 
        shape_class = (SPShapeClass *) klass;
86
 
 
87
 
        parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
88
 
 
89
 
        sp_object_class->build = sp_star_build;
90
 
        sp_object_class->write = sp_star_write;
91
 
        sp_object_class->set = sp_star_set;
92
 
        sp_object_class->update = sp_star_update;
93
 
 
94
 
        item_class->description = sp_star_description;
95
 
        item_class->snappoints = sp_star_snappoints;
 
75
    GObjectClass * gobject_class;
 
76
    SPObjectClass * sp_object_class;
 
77
    SPItemClass * item_class;
 
78
    SPLPEItemClass * lpe_item_class;
 
79
    SPShapeClass * shape_class;
 
80
 
 
81
    gobject_class = (GObjectClass *) klass;
 
82
    sp_object_class = (SPObjectClass *) klass;
 
83
    item_class = (SPItemClass *) klass;
 
84
    lpe_item_class = (SPLPEItemClass *) klass;
 
85
    shape_class = (SPShapeClass *) klass;
 
86
 
 
87
    parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
 
88
 
 
89
    sp_object_class->build = sp_star_build;
 
90
    sp_object_class->write = sp_star_write;
 
91
    sp_object_class->set = sp_star_set;
 
92
    sp_object_class->update = sp_star_update;
 
93
 
 
94
    item_class->description = sp_star_description;
 
95
    item_class->snappoints = sp_star_snappoints;
96
96
 
97
97
    lpe_item_class->update_patheffect = sp_star_update_patheffect;
98
98
 
99
 
        shape_class->set_shape = sp_star_set_shape;
 
99
    shape_class->set_shape = sp_star_set_shape;
100
100
}
101
101
 
102
102
static void
103
103
sp_star_init (SPStar * star)
104
104
{
105
 
        star->sides = 5;
106
 
        star->center = Geom::Point(0, 0);
107
 
        star->r[0] = 1.0;
108
 
        star->r[1] = 0.001;
109
 
        star->arg[0] = star->arg[1] = 0.0;
110
 
        star->flatsided = 0;
111
 
        star->rounded = 0.0;
112
 
        star->randomized = 0.0;
 
105
    star->sides = 5;
 
106
    star->center = Geom::Point(0, 0);
 
107
    star->r[0] = 1.0;
 
108
    star->r[1] = 0.001;
 
109
    star->arg[0] = star->arg[1] = 0.0;
 
110
    star->flatsided = 0;
 
111
    star->rounded = 0.0;
 
112
    star->randomized = 0.0;
113
113
}
114
114
 
115
115
static void
116
116
sp_star_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr)
117
117
{
118
 
        if (((SPObjectClass *) parent_class)->build)
119
 
                ((SPObjectClass *) parent_class)->build (object, document, repr);
 
118
    if (((SPObjectClass *) parent_class)->build)
 
119
        ((SPObjectClass *) parent_class)->build (object, document, repr);
120
120
 
121
 
        sp_object_read_attr (object, "sodipodi:cx");
122
 
        sp_object_read_attr (object, "sodipodi:cy");
123
 
        sp_object_read_attr (object, "sodipodi:sides");
124
 
        sp_object_read_attr (object, "sodipodi:r1");
125
 
        sp_object_read_attr (object, "sodipodi:r2");
126
 
        sp_object_read_attr (object, "sodipodi:arg1");
127
 
        sp_object_read_attr (object, "sodipodi:arg2");
128
 
        sp_object_read_attr (object, "inkscape:flatsided");
129
 
        sp_object_read_attr (object, "inkscape:rounded");
130
 
        sp_object_read_attr (object, "inkscape:randomized");
 
121
    sp_object_read_attr (object, "sodipodi:cx");
 
122
    sp_object_read_attr (object, "sodipodi:cy");
 
123
    sp_object_read_attr (object, "sodipodi:sides");
 
124
    sp_object_read_attr (object, "sodipodi:r1");
 
125
    sp_object_read_attr (object, "sodipodi:r2");
 
126
    sp_object_read_attr (object, "sodipodi:arg1");
 
127
    sp_object_read_attr (object, "sodipodi:arg2");
 
128
    sp_object_read_attr (object, "inkscape:flatsided");
 
129
    sp_object_read_attr (object, "inkscape:rounded");
 
130
    sp_object_read_attr (object, "inkscape:randomized");
131
131
}
132
132
 
133
133
static Inkscape::XML::Node *
134
134
sp_star_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
135
135
{
136
 
        SPStar *star = SP_STAR (object);
137
 
 
138
 
        if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
139
 
                repr = xml_doc->createElement("svg:path");
140
 
        }
141
 
 
142
 
        if (flags & SP_OBJECT_WRITE_EXT) {
143
 
                repr->setAttribute("sodipodi:type", "star");
144
 
                sp_repr_set_int (repr, "sodipodi:sides", star->sides);
145
 
                sp_repr_set_svg_double(repr, "sodipodi:cx", star->center[Geom::X]);
146
 
                sp_repr_set_svg_double(repr, "sodipodi:cy", star->center[Geom::Y]);
147
 
                sp_repr_set_svg_double(repr, "sodipodi:r1", star->r[0]);
148
 
                sp_repr_set_svg_double(repr, "sodipodi:r2", star->r[1]);
149
 
                sp_repr_set_svg_double(repr, "sodipodi:arg1", star->arg[0]);
150
 
                sp_repr_set_svg_double(repr, "sodipodi:arg2", star->arg[1]);
151
 
                sp_repr_set_boolean (repr, "inkscape:flatsided", star->flatsided);
152
 
                sp_repr_set_svg_double(repr, "inkscape:rounded", star->rounded);
153
 
                sp_repr_set_svg_double(repr, "inkscape:randomized", star->randomized);
154
 
        }
 
136
    SPStar *star = SP_STAR (object);
 
137
 
 
138
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
 
139
        repr = xml_doc->createElement("svg:path");
 
140
    }
 
141
 
 
142
    if (flags & SP_OBJECT_WRITE_EXT) {
 
143
        repr->setAttribute("sodipodi:type", "star");
 
144
        sp_repr_set_int (repr, "sodipodi:sides", star->sides);
 
145
        sp_repr_set_svg_double(repr, "sodipodi:cx", star->center[Geom::X]);
 
146
        sp_repr_set_svg_double(repr, "sodipodi:cy", star->center[Geom::Y]);
 
147
        sp_repr_set_svg_double(repr, "sodipodi:r1", star->r[0]);
 
148
        sp_repr_set_svg_double(repr, "sodipodi:r2", star->r[1]);
 
149
        sp_repr_set_svg_double(repr, "sodipodi:arg1", star->arg[0]);
 
150
        sp_repr_set_svg_double(repr, "sodipodi:arg2", star->arg[1]);
 
151
        sp_repr_set_boolean (repr, "inkscape:flatsided", star->flatsided);
 
152
        sp_repr_set_svg_double(repr, "inkscape:rounded", star->rounded);
 
153
        sp_repr_set_svg_double(repr, "inkscape:randomized", star->randomized);
 
154
    }
155
155
 
156
156
    sp_star_set_shape ((SPShape *) star);
157
157
    char *d = sp_svg_write_path (((SPShape *) star)->curve->get_pathvector());
158
158
    repr->setAttribute("d", d);
159
159
    g_free (d);
160
160
 
161
 
        if (((SPObjectClass *) (parent_class))->write)
162
 
                ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
 
161
    if (((SPObjectClass *) (parent_class))->write)
 
162
        ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
163
163
 
164
 
        return repr;
 
164
    return repr;
165
165
}
166
166
 
167
167
static void
168
168
sp_star_set (SPObject *object, unsigned int key, const gchar *value)
169
169
{
170
 
        SVGLength::Unit unit;
171
 
 
172
 
        SPStar *star = SP_STAR (object);
173
 
 
174
 
        /* fixme: we should really collect updates */
175
 
        switch (key) {
176
 
        case SP_ATTR_SODIPODI_SIDES:
177
 
                if (value) {
178
 
                        star->sides = atoi (value);
179
 
                        star->sides = NR_CLAMP(star->sides, 3, 1024);
180
 
                } else {
181
 
                        star->sides = 5;
182
 
                }
183
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
184
 
                break;
185
 
        case SP_ATTR_SODIPODI_CX:
186
 
                if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::X]) ||
187
 
                    (unit == SVGLength::EM) ||
188
 
                    (unit == SVGLength::EX) ||
189
 
                    (unit == SVGLength::PERCENT)) {
190
 
                        star->center[Geom::X] = 0.0;
191
 
                }
192
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
193
 
                break;
194
 
        case SP_ATTR_SODIPODI_CY:
195
 
                if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::Y]) ||
196
 
                    (unit == SVGLength::EM) ||
197
 
                    (unit == SVGLength::EX) ||
198
 
                    (unit == SVGLength::PERCENT)) {
199
 
                        star->center[Geom::Y] = 0.0;
200
 
                }
201
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
202
 
                break;
203
 
        case SP_ATTR_SODIPODI_R1:
204
 
                if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[0]) ||
205
 
                    (unit == SVGLength::EM) ||
206
 
                    (unit == SVGLength::EX) ||
207
 
                    (unit == SVGLength::PERCENT)) {
208
 
                        star->r[0] = 1.0;
209
 
                }
210
 
                /* fixme: Need CLAMP (Lauris) */
211
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
212
 
                break;
213
 
        case SP_ATTR_SODIPODI_R2:
214
 
                if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[1]) ||
215
 
                    (unit == SVGLength::EM) ||
216
 
                    (unit == SVGLength::EX) ||
217
 
                    (unit == SVGLength::PERCENT)) {
218
 
                        star->r[1] = 0.0;
219
 
                }
220
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
221
 
                return;
222
 
        case SP_ATTR_SODIPODI_ARG1:
223
 
                if (value) {
224
 
                        star->arg[0] = g_ascii_strtod (value, NULL);
225
 
                } else {
226
 
                        star->arg[0] = 0.0;
227
 
                }
228
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
229
 
                break;
230
 
        case SP_ATTR_SODIPODI_ARG2:
231
 
                if (value) {
232
 
                        star->arg[1] = g_ascii_strtod (value, NULL);
233
 
                } else {
234
 
                        star->arg[1] = 0.0;
235
 
                }
236
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
237
 
                break;
238
 
        case SP_ATTR_INKSCAPE_FLATSIDED:
239
 
                if (value && !strcmp (value, "true"))
240
 
                        star->flatsided = true;
241
 
                else star->flatsided = false;
242
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
243
 
                break;
244
 
        case SP_ATTR_INKSCAPE_ROUNDED:
245
 
                if (value) {
246
 
                        star->rounded = g_ascii_strtod (value, NULL);
247
 
                } else {
248
 
                        star->rounded = 0.0;
249
 
                }
250
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
251
 
                break;
252
 
        case SP_ATTR_INKSCAPE_RANDOMIZED:
253
 
                if (value) {
254
 
                        star->randomized = g_ascii_strtod (value, NULL);
255
 
                } else {
256
 
                        star->randomized = 0.0;
257
 
                }
258
 
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
259
 
                break;
260
 
        default:
261
 
                if (((SPObjectClass *) parent_class)->set)
262
 
                        ((SPObjectClass *) parent_class)->set (object, key, value);
263
 
                break;
264
 
        }
 
170
    SVGLength::Unit unit;
 
171
 
 
172
    SPStar *star = SP_STAR (object);
 
173
 
 
174
    /* fixme: we should really collect updates */
 
175
    switch (key) {
 
176
    case SP_ATTR_SODIPODI_SIDES:
 
177
        if (value) {
 
178
            star->sides = atoi (value);
 
179
            star->sides = NR_CLAMP(star->sides, 3, 1024);
 
180
        } else {
 
181
            star->sides = 5;
 
182
        }
 
183
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
184
        break;
 
185
    case SP_ATTR_SODIPODI_CX:
 
186
        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::X]) ||
 
187
            (unit == SVGLength::EM) ||
 
188
            (unit == SVGLength::EX) ||
 
189
            (unit == SVGLength::PERCENT)) {
 
190
            star->center[Geom::X] = 0.0;
 
191
        }
 
192
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
193
        break;
 
194
    case SP_ATTR_SODIPODI_CY:
 
195
        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::Y]) ||
 
196
            (unit == SVGLength::EM) ||
 
197
            (unit == SVGLength::EX) ||
 
198
            (unit == SVGLength::PERCENT)) {
 
199
            star->center[Geom::Y] = 0.0;
 
200
        }
 
201
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
202
        break;
 
203
    case SP_ATTR_SODIPODI_R1:
 
204
        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[0]) ||
 
205
            (unit == SVGLength::EM) ||
 
206
            (unit == SVGLength::EX) ||
 
207
            (unit == SVGLength::PERCENT)) {
 
208
            star->r[0] = 1.0;
 
209
        }
 
210
        /* fixme: Need CLAMP (Lauris) */
 
211
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
212
        break;
 
213
    case SP_ATTR_SODIPODI_R2:
 
214
        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[1]) ||
 
215
            (unit == SVGLength::EM) ||
 
216
            (unit == SVGLength::EX) ||
 
217
            (unit == SVGLength::PERCENT)) {
 
218
            star->r[1] = 0.0;
 
219
        }
 
220
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
221
        return;
 
222
    case SP_ATTR_SODIPODI_ARG1:
 
223
        if (value) {
 
224
            star->arg[0] = g_ascii_strtod (value, NULL);
 
225
        } else {
 
226
            star->arg[0] = 0.0;
 
227
        }
 
228
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
229
        break;
 
230
    case SP_ATTR_SODIPODI_ARG2:
 
231
        if (value) {
 
232
            star->arg[1] = g_ascii_strtod (value, NULL);
 
233
        } else {
 
234
            star->arg[1] = 0.0;
 
235
        }
 
236
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
237
        break;
 
238
    case SP_ATTR_INKSCAPE_FLATSIDED:
 
239
        if (value && !strcmp (value, "true"))
 
240
            star->flatsided = true;
 
241
        else star->flatsided = false;
 
242
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
243
        break;
 
244
    case SP_ATTR_INKSCAPE_ROUNDED:
 
245
        if (value) {
 
246
            star->rounded = g_ascii_strtod (value, NULL);
 
247
        } else {
 
248
            star->rounded = 0.0;
 
249
        }
 
250
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
251
        break;
 
252
    case SP_ATTR_INKSCAPE_RANDOMIZED:
 
253
        if (value) {
 
254
            star->randomized = g_ascii_strtod (value, NULL);
 
255
        } else {
 
256
            star->randomized = 0.0;
 
257
        }
 
258
        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
259
        break;
 
260
    default:
 
261
        if (((SPObjectClass *) parent_class)->set)
 
262
            ((SPObjectClass *) parent_class)->set (object, key, value);
 
263
        break;
 
264
    }
265
265
}
266
266
 
267
267
static void
268
268
sp_star_update (SPObject *object, SPCtx *ctx, guint flags)
269
269
{
270
 
        if (flags & (SP_OBJECT_MODIFIED_FLAG |
271
 
                     SP_OBJECT_STYLE_MODIFIED_FLAG |
272
 
                     SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
273
 
                sp_shape_set_shape ((SPShape *) object);
274
 
        }
 
270
    if (flags & (SP_OBJECT_MODIFIED_FLAG |
 
271
             SP_OBJECT_STYLE_MODIFIED_FLAG |
 
272
             SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
 
273
        sp_shape_set_shape ((SPShape *) object);
 
274
    }
275
275
 
276
 
        if (((SPObjectClass *) parent_class)->update)
277
 
                ((SPObjectClass *) parent_class)->update (object, ctx, flags);
 
276
    if (((SPObjectClass *) parent_class)->update)
 
277
        ((SPObjectClass *) parent_class)->update (object, ctx, flags);
278
278
}
279
279
 
280
280
static void
306
306
    // make calls to ngettext because the pluralization may be different
307
307
    // for various numbers >=3.  The singular form is used as the index.
308
308
    if (star->flatsided == false )
309
 
        return g_strdup_printf (ngettext("<b>Star</b> with %d vertex",
310
 
                                         "<b>Star</b> with %d vertices",
311
 
                                         star->sides), star->sides);
 
309
    return g_strdup_printf (ngettext("<b>Star</b> with %d vertex",
 
310
                         "<b>Star</b> with %d vertices",
 
311
                     star->sides), star->sides);
312
312
    else
313
313
        return g_strdup_printf (ngettext("<b>Polygon</b> with %d vertex",
314
 
                                         "<b>Polygon</b> with %d vertices",
315
 
                                         star->sides), star->sides);
 
314
                         "<b>Polygon</b> with %d vertices",
 
315
                     star->sides), star->sides);
316
316
}
317
317
 
318
318
/**
321
321
static Geom::Point
322
322
rot90_rel (Geom::Point o, Geom::Point n)
323
323
{
324
 
        return ((1/Geom::L2(n - o)) * Geom::Point ((n - o)[Geom::Y],  (o - n)[Geom::X]));
 
324
    return ((1/Geom::L2(n - o)) * Geom::Point ((n - o)[Geom::Y],  (o - n)[Geom::X]));
325
325
}
326
326
 
327
327
/**
333
333
static guint32
334
334
point_unique_int (Geom::Point o)
335
335
{
336
 
        return ((guint32)
337
 
        65536 *
338
 
                (((int) floor (o[Geom::X] * 64)) % 1024 + ((int) floor (o[Geom::X] * 1024)) % 64)
339
 
        +
340
 
                (((int) floor (o[Geom::Y] * 64)) % 1024 + ((int) floor (o[Geom::Y] * 1024)) % 64)
341
 
        );
 
336
    return ((guint32)
 
337
    65536 *
 
338
        (((int) floor (o[Geom::X] * 64)) % 1024 + ((int) floor (o[Geom::X] * 1024)) % 64)
 
339
    +
 
340
             (((int) floor (o[Geom::Y] * 64)) % 1024 + ((int) floor (o[Geom::Y] * 1024)) % 64)
 
341
    );
342
342
}
343
343
 
344
344
/**
349
349
static inline guint32
350
350
lcg_next(guint32 const prev)
351
351
{
352
 
        return (guint32) ( 69069 * prev + 1 );
 
352
    return (guint32) ( 69069 * prev + 1 );
353
353
}
354
354
 
355
355
/**
357
357
*/
358
358
static double
359
359
rnd (guint32 const seed, unsigned steps) {
360
 
        guint32 lcg = seed;
361
 
        for (; steps > 0; steps --)
362
 
                lcg = lcg_next (lcg);
 
360
    guint32 lcg = seed;
 
361
    for (; steps > 0; steps --)
 
362
        lcg = lcg_next (lcg);
363
363
 
364
 
        return ( lcg / 4294967296. ) - 0.5;
 
364
    return ( lcg / 4294967296. ) - 0.5;
365
365
}
366
366
 
367
367
static Geom::Point
368
368
sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ)
369
369
{
370
 
        // the point whose neighboring curve handle we're calculating
371
 
        Geom::Point o = sp_star_get_xy (star, point, index);
372
 
 
373
 
        // indices of previous and next points
374
 
        gint pi = (index > 0)? (index - 1) : (star->sides - 1);
375
 
        gint ni = (index < star->sides - 1)? (index + 1) : 0;
376
 
 
377
 
        // the other point type
378
 
        SPStarPoint other = (point == SP_STAR_POINT_KNOT2? SP_STAR_POINT_KNOT1 : SP_STAR_POINT_KNOT2);
379
 
 
380
 
        // the neighbors of o; depending on flatsided, they're either the same type (polygon) or the other type (star)
381
 
        Geom::Point prev = (star->flatsided? sp_star_get_xy (star, point, pi) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT2? index : pi));
382
 
        Geom::Point next = (star->flatsided? sp_star_get_xy (star, point, ni) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT1? index : ni));
383
 
 
384
 
        // prev-next midpoint
385
 
        Geom::Point mid =  0.5 * (prev + next);
386
 
 
387
 
        // point to which we direct the bissector of the curve handles;
388
 
        // it's far enough outside the star on the perpendicular to prev-next through mid
389
 
        Geom::Point biss =  mid + 100000 * rot90_rel (mid, next);
390
 
 
391
 
        // lengths of vectors to prev and next
392
 
        gdouble prev_len = Geom::L2 (prev - o);
393
 
        gdouble next_len = Geom::L2 (next - o);
394
 
 
395
 
        // unit-length vector perpendicular to o-biss
396
 
        Geom::Point rot = rot90_rel (o, biss);
397
 
 
398
 
        // multiply rot by star->rounded coefficient and the distance to the star point; flip for next
399
 
        Geom::Point ret;
400
 
        if (previ) {
401
 
                ret = (star->rounded * prev_len) * rot;
402
 
        } else {
403
 
                ret = (star->rounded * next_len * -1) * rot;
404
 
        }
405
 
 
406
 
        if (star->randomized == 0) {
407
 
                // add the vector to o to get the final curvepoint
408
 
                return o + ret;
409
 
        } else {
410
 
                // the seed corresponding to the exact point
411
 
                guint32 seed = point_unique_int (o);
412
 
 
413
 
                // randomly rotate (by step 3 from the seed) and scale (by step 4) the vector
414
 
                ret = ret * Geom::Matrix (Geom::Rotate (star->randomized * M_PI * rnd (seed, 3)));
415
 
                ret *= ( 1 + star->randomized * rnd (seed, 4));
416
 
 
417
 
                // the randomized corner point
418
 
                Geom::Point o_randomized = sp_star_get_xy (star, point, index, true);
419
 
 
420
 
                return o_randomized + ret;
421
 
        }
 
370
    // the point whose neighboring curve handle we're calculating
 
371
    Geom::Point o = sp_star_get_xy (star, point, index);
 
372
 
 
373
    // indices of previous and next points
 
374
    gint pi = (index > 0)? (index - 1) : (star->sides - 1);
 
375
    gint ni = (index < star->sides - 1)? (index + 1) : 0;
 
376
 
 
377
    // the other point type
 
378
    SPStarPoint other = (point == SP_STAR_POINT_KNOT2? SP_STAR_POINT_KNOT1 : SP_STAR_POINT_KNOT2);
 
379
 
 
380
    // the neighbors of o; depending on flatsided, they're either the same type (polygon) or the other type (star)
 
381
    Geom::Point prev = (star->flatsided? sp_star_get_xy (star, point, pi) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT2? index : pi));
 
382
    Geom::Point next = (star->flatsided? sp_star_get_xy (star, point, ni) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT1? index : ni));
 
383
 
 
384
    // prev-next midpoint
 
385
    Geom::Point mid =  0.5 * (prev + next);
 
386
 
 
387
    // point to which we direct the bissector of the curve handles;
 
388
    // it's far enough outside the star on the perpendicular to prev-next through mid
 
389
    Geom::Point biss =  mid + 100000 * rot90_rel (mid, next);
 
390
 
 
391
    // lengths of vectors to prev and next
 
392
    gdouble prev_len = Geom::L2 (prev - o);
 
393
    gdouble next_len = Geom::L2 (next - o);
 
394
 
 
395
    // unit-length vector perpendicular to o-biss
 
396
    Geom::Point rot = rot90_rel (o, biss);
 
397
 
 
398
    // multiply rot by star->rounded coefficient and the distance to the star point; flip for next
 
399
    Geom::Point ret;
 
400
    if (previ) {
 
401
        ret = (star->rounded * prev_len) * rot;
 
402
    } else {
 
403
        ret = (star->rounded * next_len * -1) * rot;
 
404
    }
 
405
 
 
406
    if (star->randomized == 0) {
 
407
        // add the vector to o to get the final curvepoint
 
408
        return o + ret;
 
409
    } else {
 
410
        // the seed corresponding to the exact point
 
411
        guint32 seed = point_unique_int (o);
 
412
 
 
413
        // randomly rotate (by step 3 from the seed) and scale (by step 4) the vector
 
414
        ret = ret * Geom::Matrix (Geom::Rotate (star->randomized * M_PI * rnd (seed, 3)));
 
415
        ret *= ( 1 + star->randomized * rnd (seed, 4));
 
416
 
 
417
        // the randomized corner point
 
418
        Geom::Point o_randomized = sp_star_get_xy (star, point, index, true);
 
419
 
 
420
        return o_randomized + ret;
 
421
    }
422
422
}
423
423
 
424
424
 
428
428
static void
429
429
sp_star_set_shape (SPShape *shape)
430
430
{
431
 
        SPStar *star = SP_STAR (shape);
 
431
    SPStar *star = SP_STAR (shape);
432
432
 
433
433
    // perhaps we should convert all our shapes into LPEs without source path
434
434
    // and with knotholders for parameters, then this situation will be handled automatically
445
445
        return;
446
446
    }
447
447
 
448
 
        SPCurve *c = new SPCurve ();
449
 
 
450
 
        gint sides = star->sides;
451
 
        bool not_rounded = (fabs (star->rounded) < 1e-4);
452
 
 
453
 
        // note that we pass randomized=true to sp_star_get_xy, because the curve must be randomized;
454
 
        // other places that call that function (e.g. the knotholder) need the exact point
455
 
 
456
 
        // draw 1st segment
457
 
        c->moveto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
458
 
        if (star->flatsided == false) {
459
 
                if (not_rounded) {
460
 
                        c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
461
 
                } else {
462
 
                        c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, NEXT),
463
 
                                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, 0, PREV),
464
 
                                sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
465
 
                }
466
 
        }
467
 
 
468
 
        // draw all middle segments
469
 
        for (gint i = 1; i < sides; i++) {
470
 
                if (not_rounded) {
471
 
                        c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
472
 
                } else {
473
 
                        if (star->flatsided == false) {
474
 
                                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i - 1, NEXT),
475
 
                                                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
476
 
                                                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
477
 
                        } else {
478
 
                                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i - 1, NEXT),
479
 
                                                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
480
 
                                                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
481
 
                        }
482
 
                }
483
 
                if (star->flatsided == false) {
484
 
 
485
 
                        if (not_rounded) {
 
448
    SPCurve *c = new SPCurve ();
 
449
 
 
450
    gint sides = star->sides;
 
451
    bool not_rounded = (fabs (star->rounded) < 1e-4);
 
452
 
 
453
    // note that we pass randomized=true to sp_star_get_xy, because the curve must be randomized;
 
454
    // other places that call that function (e.g. the knotholder) need the exact point
 
455
 
 
456
    // draw 1st segment
 
457
    c->moveto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
 
458
    if (star->flatsided == false) {
 
459
        if (not_rounded) {
 
460
            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
 
461
        } else {
 
462
            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, NEXT),
 
463
                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, 0, PREV),
 
464
                sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
 
465
        }
 
466
    }
 
467
 
 
468
    // draw all middle segments
 
469
    for (gint i = 1; i < sides; i++) {
 
470
        if (not_rounded) {
 
471
            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
 
472
        } else {
 
473
            if (star->flatsided == false) {
 
474
                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i - 1, NEXT),
 
475
                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
 
476
                        sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
 
477
            } else {
 
478
                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i - 1, NEXT),
 
479
                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
 
480
                        sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
 
481
            }
 
482
        }
 
483
        if (star->flatsided == false) {
 
484
 
 
485
            if (not_rounded) {
486
486
                       c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
487
 
                        } else {
488
 
                                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, NEXT),
489
 
                                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i, PREV),
490
 
                                        sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
491
 
                        }
492
 
                }
493
 
        }
 
487
            } else {
 
488
                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, NEXT),
 
489
                    sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i, PREV),
 
490
                    sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
 
491
            }
 
492
        }
 
493
    }
494
494
 
495
 
        // draw last segment
496
 
                if (not_rounded) {
497
 
                        c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
498
 
                } else {
499
 
                        if (star->flatsided == false) {
500
 
                        c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, sides - 1, NEXT),
501
 
                                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
502
 
                                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
503
 
                        } else {
504
 
                        c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, sides - 1, NEXT),
505
 
                                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
506
 
                                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
507
 
                        }
508
 
                }
 
495
    // draw last segment
 
496
        if (!not_rounded) {
 
497
            if (star->flatsided == false) {
 
498
            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, sides - 1, NEXT),
 
499
                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
 
500
                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
 
501
            } else {
 
502
            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, sides - 1, NEXT),
 
503
                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
 
504
                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
 
505
            }
 
506
        }
509
507
 
510
508
    c->closepath();
511
509
 
526
524
void
527
525
sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1, gdouble r2, gdouble arg1, gdouble arg2, bool isflat, double rounded, double randomized)
528
526
{
529
 
        g_return_if_fail (star != NULL);
530
 
        g_return_if_fail (SP_IS_STAR (star));
 
527
    g_return_if_fail (star != NULL);
 
528
    g_return_if_fail (SP_IS_STAR (star));
531
529
 
532
 
        star->sides = NR_CLAMP(sides, 3, 1024);
533
 
        star->center = center;
534
 
        star->r[0] = MAX (r1, 0.001);
535
 
        if (isflat == false) {
536
 
                star->r[1] = NR_CLAMP(r2, 0.0, star->r[0]);
537
 
        } else {
538
 
                star->r[1] = NR_CLAMP( r1*cos(M_PI/sides) ,0.0, star->r[0] );
539
 
        }
540
 
        star->arg[0] = arg1;
541
 
        star->arg[1] = arg2;
542
 
        star->flatsided = isflat;
543
 
        star->rounded = rounded;
544
 
        star->randomized = randomized;
545
 
        SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
530
    star->sides = NR_CLAMP(sides, 3, 1024);
 
531
    star->center = center;
 
532
    star->r[0] = MAX (r1, 0.001);
 
533
    if (isflat == false) {
 
534
        star->r[1] = NR_CLAMP(r2, 0.0, star->r[0]);
 
535
    } else {
 
536
        star->r[1] = NR_CLAMP( r1*cos(M_PI/sides) ,0.0, star->r[0] );
 
537
    }
 
538
    star->arg[0] = arg1;
 
539
    star->arg[1] = arg2;
 
540
    star->flatsided = isflat;
 
541
    star->rounded = rounded;
 
542
    star->randomized = randomized;
 
543
    SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
546
544
}
547
545
 
548
 
static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 
546
static void sp_star_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
549
547
{
550
 
        // We will determine the star's midpoint ourselves, instead of trusting on the base class
551
 
        // Therefore setSnapObjectMidpoints() is set to false temporarily
552
 
        Inkscape::SnapPreferences local_snapprefs = *snapprefs;
553
 
        local_snapprefs.setSnapObjectMidpoints(false);
554
 
 
555
 
        if (((SPItemClass *) parent_class)->snappoints) {
556
 
                ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
557
 
        }
558
 
 
559
 
        // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
560
 
        if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
561
 
                return;
562
 
        }
563
 
 
564
 
        if (snapprefs->getSnapObjectMidpoints()) {
565
 
                Geom::Matrix const i2d (sp_item_i2d_affine (item));
566
 
                int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
567
 
                p.push_back(std::make_pair(SP_STAR(item)->center * i2d, type));
568
 
        }
 
548
    // We will determine the star's midpoint ourselves, instead of trusting on the base class
 
549
    // Therefore setSnapObjectMidpoints() is set to false temporarily
 
550
    Inkscape::SnapPreferences local_snapprefs = *snapprefs;
 
551
    local_snapprefs.setSnapObjectMidpoints(false);
 
552
 
 
553
    if (((SPItemClass *) parent_class)->snappoints) {
 
554
        ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
 
555
    }
 
556
 
 
557
    // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
 
558
    if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
 
559
        return;
 
560
    }
 
561
 
 
562
    if (snapprefs->getSnapObjectMidpoints()) {
 
563
        Geom::Matrix const i2d (sp_item_i2d_affine (item));
 
564
        p.push_back(Inkscape::SnapCandidatePoint(SP_STAR(item)->center * i2d,Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
 
565
    }
569
566
}
570
567
 
571
568
/**
582
579
Geom::Point
583
580
sp_star_get_xy (SPStar *star, SPStarPoint point, gint index, bool randomized)
584
581
{
585
 
        gdouble darg = 2.0 * M_PI / (double) star->sides;
586
 
 
587
 
        double arg = star->arg[point];
588
 
        arg += index * darg;
589
 
 
590
 
        Geom::Point xy = star->r[point] * Geom::Point(cos(arg), sin(arg)) + star->center;
591
 
 
592
 
        if (!randomized || star->randomized == 0) {
593
 
                // return the exact point
594
 
                return xy;
595
 
        } else { // randomize the point
596
 
                // find out the seed, unique for this point so that randomization is the same so long as the original point is stationary
597
 
                guint32 seed = point_unique_int (xy);
598
 
                // the full range (corresponding to star->randomized == 1.0) is equal to the star's diameter
599
 
                double range = 2 * MAX (star->r[0], star->r[1]);
600
 
                // find out the random displacement; x is controlled by step 1 from the seed, y by the step 2
601
 
                Geom::Point shift (star->randomized * range * rnd (seed, 1), star->randomized * range * rnd (seed, 2));
602
 
                // add the shift to the exact point
603
 
                return xy + shift;
604
 
        }
 
582
    gdouble darg = 2.0 * M_PI / (double) star->sides;
 
583
 
 
584
    double arg = star->arg[point];
 
585
    arg += index * darg;
 
586
 
 
587
    Geom::Point xy = star->r[point] * Geom::Point(cos(arg), sin(arg)) + star->center;
 
588
 
 
589
    if (!randomized || star->randomized == 0) {
 
590
        // return the exact point
 
591
        return xy;
 
592
    } else { // randomize the point
 
593
        // find out the seed, unique for this point so that randomization is the same so long as the original point is stationary
 
594
        guint32 seed = point_unique_int (xy);
 
595
        // the full range (corresponding to star->randomized == 1.0) is equal to the star's diameter
 
596
        double range = 2 * MAX (star->r[0], star->r[1]);
 
597
        // find out the random displacement; x is controlled by step 1 from the seed, y by the step 2
 
598
        Geom::Point shift (star->randomized * range * rnd (seed, 1), star->randomized * range * rnd (seed, 2));
 
599
        // add the shift to the exact point
 
600
        return xy + shift;
 
601
    }
605
602
}
606
603
 
607
604
/*