~centralelyon2010/inkscape/imagelinks2

1 by mental
moving trunk for module inkscape
1
/*
2
 * <sodipodi:star> implementation
3
 *
4
 * Authors:
5
 *   Mitsuru Oka <oka326@parkcity.ne.jp>
6
 *   Lauris Kaplinski <lauris@kaplinski.com>
7
 *   bulia byak <buliabyak@users.sf.net>
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
8
 *   Abhishek Sharma
1 by mental
moving trunk for module inkscape
9
 *
10
 * Copyright (C) 1999-2002 Lauris Kaplinski
11
 * Copyright (C) 2000-2001 Ximian, Inc.
12
 *
13
 * Released under GNU GPL, read the file 'COPYING' for more information
14
 */
15
4629 by bryce
Applying fixes for gcc 4.3 build issues (closes LP: #169115)
16
#ifdef HAVE_CONFIG_H
17
# include "config.h"
18
#endif
1 by mental
moving trunk for module inkscape
19
4629 by bryce
Applying fixes for gcc 4.3 build issues (closes LP: #169115)
20
#include <cstring>
21
#include <string>
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
22
#include <glib.h>
1176 by joncruz
Applied patch #1501709
23
#include <glibmm/i18n.h>
1 by mental
moving trunk for module inkscape
24
25
#include "svg/svg.h"
26
#include "attributes.h"
27
#include "display/curve.h"
28
#include "xml/repr.h"
2257 by acspike
continue switching sp_repr_new* over to XML::Document::create*
29
#include "document.h"
1 by mental
moving trunk for module inkscape
30
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
31
#include <2geom/pathvector.h>
32
1 by mental
moving trunk for module inkscape
33
#include "sp-star.h"
34
35
static void sp_star_class_init (SPStarClass *klass);
36
static void sp_star_init (SPStar *star);
37
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
38
static void sp_star_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr);
5884 by mental
plumb XML::Documents in everywhere
39
static Inkscape::XML::Node *sp_star_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
1 by mental
moving trunk for module inkscape
40
static void sp_star_set (SPObject *object, unsigned int key, const gchar *value);
41
static void sp_star_update (SPObject *object, SPCtx *ctx, guint flags);
42
43
static gchar * sp_star_description (SPItem * item);
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
44
static void sp_star_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
1 by mental
moving trunk for module inkscape
45
46
static void sp_star_set_shape (SPShape *shape);
5219 by bgk
- Created a SPLPEItem class that handles applying a LPE to an Item
47
static void sp_star_update_patheffect (SPLPEItem *lpeitem, bool write);
1 by mental
moving trunk for module inkscape
48
49
static SPShapeClass *parent_class;
50
51
GType
52
sp_star_get_type (void)
53
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
54
    static GType type = 0;
1 by mental
moving trunk for module inkscape
55
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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;
1 by mental
moving trunk for module inkscape
70
}
71
72
static void
73
sp_star_class_init (SPStarClass *klass)
74
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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;
1 by mental
moving trunk for module inkscape
96
5219 by bgk
- Created a SPLPEItem class that handles applying a LPE to an Item
97
    lpe_item_class->update_patheffect = sp_star_update_patheffect;
98
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
99
    shape_class->set_shape = sp_star_set_shape;
1 by mental
moving trunk for module inkscape
100
}
101
102
static void
103
sp_star_init (SPStar * star)
104
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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;
1 by mental
moving trunk for module inkscape
113
}
114
115
static void
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
116
sp_star_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr)
1 by mental
moving trunk for module inkscape
117
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
118
    if (((SPObjectClass *) parent_class)->build)
119
        ((SPObjectClass *) parent_class)->build (object, document, repr);
1 by mental
moving trunk for module inkscape
120
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
121
    object->readAttr( "sodipodi:cx" );
122
    object->readAttr( "sodipodi:cy" );
123
    object->readAttr( "sodipodi:sides" );
124
    object->readAttr( "sodipodi:r1" );
125
    object->readAttr( "sodipodi:r2" );
126
    object->readAttr( "sodipodi:arg1" );
127
    object->readAttr( "sodipodi:arg2" );
128
    object->readAttr( "inkscape:flatsided" );
129
    object->readAttr( "inkscape:rounded" );
130
    object->readAttr( "inkscape:randomized" );
1 by mental
moving trunk for module inkscape
131
}
132
133
static Inkscape::XML::Node *
5884 by mental
plumb XML::Documents in everywhere
134
sp_star_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
1 by mental
moving trunk for module inkscape
135
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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
    }
1 by mental
moving trunk for module inkscape
155
5842 by johanengelen
for sp-offset.cpp and sp-star.cpp, start using 2geompath for svg_write: sp_svg_write_path(np->curve->get_pathvector() );
156
    sp_star_set_shape ((SPShape *) star);
157
    char *d = sp_svg_write_path (((SPShape *) star)->curve->get_pathvector());
158
    repr->setAttribute("d", d);
159
    g_free (d);
1 by mental
moving trunk for module inkscape
160
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
161
    if (((SPObjectClass *) (parent_class))->write)
162
        ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
1 by mental
moving trunk for module inkscape
163
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
164
    return repr;
1 by mental
moving trunk for module inkscape
165
}
166
167
static void
168
sp_star_set (SPObject *object, unsigned int key, const gchar *value)
169
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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);
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
179
            star->sides = CLAMP(star->sides, 3, 1024);
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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
    }
1 by mental
moving trunk for module inkscape
265
}
266
267
static void
268
sp_star_update (SPObject *object, SPCtx *ctx, guint flags)
269
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
270
    if (flags & (SP_OBJECT_MODIFIED_FLAG |
271
             SP_OBJECT_STYLE_MODIFIED_FLAG |
272
             SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
273
        ((SPShape *) object)->setShape ();
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
274
    }
1 by mental
moving trunk for module inkscape
275
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
276
    if (((SPObjectClass *) parent_class)->update)
277
        ((SPObjectClass *) parent_class)->update (object, ctx, flags);
1 by mental
moving trunk for module inkscape
278
}
279
3472 by johanengelen
Commit LivePathEffect branch to trunk!
280
static void
5219 by bgk
- Created a SPLPEItem class that handles applying a LPE to an Item
281
sp_star_update_patheffect(SPLPEItem *lpeitem, bool write)
3472 by johanengelen
Commit LivePathEffect branch to trunk!
282
{
5219 by bgk
- Created a SPLPEItem class that handles applying a LPE to an Item
283
    SPShape *shape = (SPShape *) lpeitem;
3472 by johanengelen
Commit LivePathEffect branch to trunk!
284
    sp_star_set_shape(shape);
285
286
    if (write) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
287
        Inkscape::XML::Node *repr = shape->getRepr();
3472 by johanengelen
Commit LivePathEffect branch to trunk!
288
        if ( shape->curve != NULL ) {
5843 by johanengelen
for sp-star.cpp, start using 2geompath for svg_write: sp_svg_write_path(np->curve->get_pathvector() ); (completed)
289
            gchar *str = sp_svg_write_path(shape->curve->get_pathvector());
290
            repr->setAttribute("d", str);
291
            g_free(str);
3472 by johanengelen
Commit LivePathEffect branch to trunk!
292
        } else {
293
            repr->setAttribute("d", NULL);
294
        }
295
    }
296
297
    ((SPObject *)shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
298
}
299
1 by mental
moving trunk for module inkscape
300
static gchar *
301
sp_star_description (SPItem *item)
302
{
303
    SPStar *star = SP_STAR (item);
304
305
    // while there will never be less than 3 vertices, we still need to
306
    // make calls to ngettext because the pluralization may be different
307
    // for various numbers >=3.  The singular form is used as the index.
308
    if (star->flatsided == false )
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
309
    return g_strdup_printf (ngettext("<b>Star</b> with %d vertex",
310
                         "<b>Star</b> with %d vertices",
311
                     star->sides), star->sides);
1 by mental
moving trunk for module inkscape
312
    else
313
        return g_strdup_printf (ngettext("<b>Polygon</b> with %d vertex",
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
314
                         "<b>Polygon</b> with %d vertices",
315
                     star->sides), star->sides);
1 by mental
moving trunk for module inkscape
316
}
317
318
/**
319
Returns a unit-length vector at 90 degrees to the direction from o to n
320
 */
6935 by verbalshadow
NR -> 2geom some headers in src/
321
static Geom::Point
322
rot90_rel (Geom::Point o, Geom::Point n)
1 by mental
moving trunk for module inkscape
323
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
324
    return ((1/Geom::L2(n - o)) * Geom::Point ((n - o)[Geom::Y],  (o - n)[Geom::X]));
1 by mental
moving trunk for module inkscape
325
}
326
327
/**
328
Returns a unique 32 bit int for a given point.
329
Obvious (but acceptable for my purposes) limits to uniqueness:
330
- returned value for x,y repeats for x+n*1024,y+n*1024
331
- returned value is unchanged when the point is moved by less than 1/1024 of px
332
*/
333
static guint32
6935 by verbalshadow
NR -> 2geom some headers in src/
334
point_unique_int (Geom::Point o)
1 by mental
moving trunk for module inkscape
335
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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
    );
1 by mental
moving trunk for module inkscape
342
}
343
344
/**
345
Returns the next pseudorandom value using the Linear Congruential Generator algorithm (LCG)
346
with the parameters (m = 2^32, a = 69069, b = 1). These parameters give a full-period generator,
347
i.e. it is guaranteed to go through all integers < 2^32 (see http://random.mat.sbg.ac.at/~charly/server/server.html)
348
*/
349
static inline guint32
350
lcg_next(guint32 const prev)
351
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
352
    return (guint32) ( 69069 * prev + 1 );
1 by mental
moving trunk for module inkscape
353
}
354
355
/**
356
Returns a random number in the range [-0.5, 0.5) from the given seed, stepping the given number of steps from the seed.
357
*/
358
static double
359
rnd (guint32 const seed, unsigned steps) {
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
360
    guint32 lcg = seed;
361
    for (; steps > 0; steps --)
362
        lcg = lcg_next (lcg);
1 by mental
moving trunk for module inkscape
363
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
364
    return ( lcg / 4294967296. ) - 0.5;
1 by mental
moving trunk for module inkscape
365
}
366
6935 by verbalshadow
NR -> 2geom some headers in src/
367
static Geom::Point
1 by mental
moving trunk for module inkscape
368
sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ)
369
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
414
        ret = ret * Geom::Affine (Geom::Rotate (star->randomized * M_PI * rnd (seed, 3)));
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
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
    }
1 by mental
moving trunk for module inkscape
422
}
423
424
425
#define NEXT false
426
#define PREV true
427
428
static void
429
sp_star_set_shape (SPShape *shape)
430
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
431
    SPStar *star = SP_STAR (shape);
1 by mental
moving trunk for module inkscape
432
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
433
    // perhaps we should convert all our shapes into LPEs without source path
434
    // and with knotholders for parameters, then this situation will be handled automatically
435
    // by disabling the entire stack (including the shape LPE)
436
    if (sp_lpe_item_has_broken_path_effect(SP_LPE_ITEM(shape))) {
437
        g_warning ("The star shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as star will remove the bad LPE");
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
438
        if (shape->getRepr()->attribute("d")) {
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
439
            // unconditionally read the curve from d, if any, to preserve appearance
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
440
            Geom::PathVector pv = sp_svg_read_pathv(shape->getRepr()->attribute("d"));
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
441
            SPCurve *cold = new SPCurve(pv);
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
442
            shape->setCurveInsync( cold, TRUE);
443
            shape->setCurveBeforeLPE(cold);
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
444
            cold->unref();
445
        }
446
        return;
447
    }
448
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
449
    SPCurve *c = new SPCurve ();
450
451
    gint sides = star->sides;
452
    bool not_rounded = (fabs (star->rounded) < 1e-4);
453
454
    // note that we pass randomized=true to sp_star_get_xy, because the curve must be randomized;
455
    // other places that call that function (e.g. the knotholder) need the exact point
456
457
    // draw 1st segment
458
    c->moveto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
459
    if (star->flatsided == false) {
460
        if (not_rounded) {
461
            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
462
        } else {
463
            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, NEXT),
464
                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, 0, PREV),
465
                sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
466
        }
467
    }
468
469
    // draw all middle segments
470
    for (gint i = 1; i < sides; i++) {
471
        if (not_rounded) {
472
            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
473
        } else {
474
            if (star->flatsided == false) {
475
                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i - 1, NEXT),
476
                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
477
                        sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
478
            } else {
479
                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i - 1, NEXT),
480
                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
481
                        sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
482
            }
483
        }
484
        if (star->flatsided == false) {
485
486
            if (not_rounded) {
5609 by johanengelen
struct SPCurve => class SPCurve
487
                       c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
488
            } else {
489
                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, NEXT),
490
                    sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i, PREV),
491
                    sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
492
            }
493
        }
494
    }
7144 by dvlierop2
- Snap to the midpoint of shapes and bboxes
495
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
496
    // draw last segment
9012.1.64 by Krzysztof Kosiński
Prevent a redundant closing line segment being added when converting
497
        if (!not_rounded) {
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
498
            if (star->flatsided == false) {
499
            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, sides - 1, NEXT),
500
                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
501
                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
502
            } else {
503
            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, sides - 1, NEXT),
504
                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
505
                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
506
            }
507
        }
1 by mental
moving trunk for module inkscape
508
5609 by johanengelen
struct SPCurve => class SPCurve
509
    c->closepath();
6891 by Ted Gould
Merge from fe-moved
510
511
    /* Reset the shape'scurve to the "original_curve"
512
     * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
513
    shape->setCurveInsync( c, TRUE);
514
    shape->setCurveBeforeLPE( c );
6891 by Ted Gould
Merge from fe-moved
515
    if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) {
516
        SPCurve *c_lpe = c->copy();
517
        bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe);
518
        if (success) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
519
            shape->setCurveInsync( c_lpe, TRUE);
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
520
        } 
6891 by Ted Gould
Merge from fe-moved
521
        c_lpe->unref();
522
    }
5609 by johanengelen
struct SPCurve => class SPCurve
523
    c->unref();
1 by mental
moving trunk for module inkscape
524
}
525
526
void
6935 by verbalshadow
NR -> 2geom some headers in src/
527
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)
1 by mental
moving trunk for module inkscape
528
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
529
    g_return_if_fail (star != NULL);
530
    g_return_if_fail (SP_IS_STAR (star));
7144 by dvlierop2
- Snap to the midpoint of shapes and bboxes
531
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
532
    star->sides = CLAMP(sides, 3, 1024);
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
533
    star->center = center;
534
    star->r[0] = MAX (r1, 0.001);
535
    if (isflat == false) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
536
        star->r[1] = CLAMP(r2, 0.0, star->r[0]);
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
537
    } else {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
538
        star->r[1] = CLAMP( r1*cos(M_PI/sides) ,0.0, star->r[0] );
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
539
    }
540
    star->arg[0] = arg1;
541
    star->arg[1] = arg2;
542
    star->flatsided = isflat;
543
    star->rounded = rounded;
544
    star->randomized = randomized;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
545
    star->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1 by mental
moving trunk for module inkscape
546
}
547
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
548
static void sp_star_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
1 by mental
moving trunk for module inkscape
549
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
550
    // We will determine the star's midpoint ourselves, instead of trusting on the base class
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
551
    // Therefore snapping to object midpoints is temporarily disabled
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
552
    Inkscape::SnapPreferences local_snapprefs = *snapprefs;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
553
    local_snapprefs.setTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT, false);
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
554
555
    if (((SPItemClass *) parent_class)->snappoints) {
556
        ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
557
    }
558
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
559
    if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT)) {
560
        Geom::Affine const i2dt (item->i2dt_affine ());
561
        p.push_back(Inkscape::SnapCandidatePoint(SP_STAR(item)->center * i2dt,Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
562
    }
1 by mental
moving trunk for module inkscape
563
}
564
565
/**
566
 * sp_star_get_xy: Get X-Y value as item coordinate system
567
 * @star: star item
568
 * @point: point type to obtain X-Y value
569
 * @index: index of vertex
570
 * @p: pointer to store X-Y value
571
 * @randomized: false (default) if you want to get exact, not randomized point
572
 *
573
 * Initial item coordinate system is same as document coordinate system.
574
 */
575
6935 by verbalshadow
NR -> 2geom some headers in src/
576
Geom::Point
1 by mental
moving trunk for module inkscape
577
sp_star_get_xy (SPStar *star, SPStarPoint point, gint index, bool randomized)
578
{
8960 by Diederik van Lierop
Refactoring the snapping API (making it easier to maintain and understand for the devs)
579
    gdouble darg = 2.0 * M_PI / (double) star->sides;
580
581
    double arg = star->arg[point];
582
    arg += index * darg;
583
584
    Geom::Point xy = star->r[point] * Geom::Point(cos(arg), sin(arg)) + star->center;
585
586
    if (!randomized || star->randomized == 0) {
587
        // return the exact point
588
        return xy;
589
    } else { // randomize the point
590
        // find out the seed, unique for this point so that randomization is the same so long as the original point is stationary
591
        guint32 seed = point_unique_int (xy);
592
        // the full range (corresponding to star->randomized == 1.0) is equal to the star's diameter
593
        double range = 2 * MAX (star->r[0], star->r[1]);
594
        // find out the random displacement; x is controlled by step 1 from the seed, y by the step 2
595
        Geom::Point shift (star->randomized * range * rnd (seed, 1), star->randomized * range * rnd (seed, 2));
596
        // add the shift to the exact point
597
        return xy + shift;
598
    }
1 by mental
moving trunk for module inkscape
599
}
600
8520 by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning
601
/*
602
  Local Variables:
603
  mode:c++
604
  c-file-style:"stroustrup"
605
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
606
  indent-tabs-mode:nil
607
  fill-column:99
608
  End:
609
*/
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
610
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :