~centralelyon2010/inkscape/imagelinks2

2077 by bryce
Renaming sp-marker.* to marker.*
1
/*
2
 * SVG <marker> implementation
3
 *
4
 * Authors:
5
 *   Lauris Kaplinski <lauris@kaplinski.com>
2080 by bryce
Marker menus now display custom markers in a document that are present
6
 *   Bryce Harrington <bryce@bryceharrington.org>
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
7
 *   Abhishek Sharma
2077 by bryce
Renaming sp-marker.* to marker.*
8
 *
9
 * Copyright (C) 1999-2003 Lauris Kaplinski
2080 by bryce
Marker menus now display custom markers in a document that are present
10
 *               2004-2006 Bryce Harrington
6007 by johanengelen
2geomify sp_shape_update_marker_view.
11
 *               2008      Johan Engelen
2077 by bryce
Renaming sp-marker.* to marker.*
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
#include <cstring>
17
#include <string>
2077 by bryce
Renaming sp-marker.* to marker.*
18
#include "config.h"
19
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
20
#include <2geom/affine.h>
21
#include <2geom/transforms.h>
2077 by bryce
Renaming sp-marker.* to marker.*
22
#include "svg/svg.h"
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
23
#include "display/drawing-group.h"
2077 by bryce
Renaming sp-marker.* to marker.*
24
#include "xml/repr.h"
25
#include "attributes.h"
26
#include "marker.h"
2253 by mental
start switching sp_repr_new* over to XML::Document::create*, and rename create methods to match DOM
27
#include "document.h"
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
28
#include "document-private.h"
2077 by bryce
Renaming sp-marker.* to marker.*
29
30
struct SPMarkerView {
31
	SPMarkerView *next;
32
	unsigned int key;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
33
  std::vector<Inkscape::DrawingItem *> items;
2077 by bryce
Renaming sp-marker.* to marker.*
34
};
35
36
static void sp_marker_class_init (SPMarkerClass *klass);
37
static void sp_marker_init (SPMarker *marker);
38
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
39
static void sp_marker_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
2077 by bryce
Renaming sp-marker.* to marker.*
40
static void sp_marker_release (SPObject *object);
41
static void sp_marker_set (SPObject *object, unsigned int key, const gchar *value);
42
static void sp_marker_update (SPObject *object, SPCtx *ctx, guint flags);
5884 by mental
plumb XML::Documents in everywhere
43
static Inkscape::XML::Node *sp_marker_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
2077 by bryce
Renaming sp-marker.* to marker.*
44
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
45
static Inkscape::DrawingItem *sp_marker_private_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
2077 by bryce
Renaming sp-marker.* to marker.*
46
static void sp_marker_private_hide (SPItem *item, unsigned int key);
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
47
static Geom::OptRect sp_marker_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
2077 by bryce
Renaming sp-marker.* to marker.*
48
static void sp_marker_print (SPItem *item, SPPrintContext *ctx);
49
50
static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems);
51
52
static SPGroupClass *parent_class;
53
54
/**
55
 * Registers the SPMarker class with Gdk and returns its type number.
56
 */
57
GType
58
sp_marker_get_type (void)
59
{
60
	static GType type = 0;
61
	if (!type) {
62
		GTypeInfo info = {
63
			sizeof (SPMarkerClass),
64
			NULL, NULL,
65
			(GClassInitFunc) sp_marker_class_init,
66
			NULL, NULL,
67
			sizeof (SPMarker),
68
			16,
69
			(GInstanceInitFunc) sp_marker_init,
70
			NULL,	/* value_table */
71
		};
72
		type = g_type_register_static (SP_TYPE_GROUP, "SPMarker", &info, (GTypeFlags)0);
73
	}
74
	return type;
75
}
76
77
/**
4043 by joncruz
warning cleanup
78
 * Initializes a SPMarkerClass object.  Establishes the function pointers to the class'
2077 by bryce
Renaming sp-marker.* to marker.*
79
 * member routines in the class vtable, and sets pointers to parent classes.
80
 */
81
static void
82
sp_marker_class_init (SPMarkerClass *klass)
83
{
84
	GObjectClass *object_class;
85
	SPObjectClass *sp_object_class;
86
	SPItemClass *sp_item_class;
87
88
	object_class = G_OBJECT_CLASS (klass);
89
	sp_object_class = (SPObjectClass *) klass;
90
	sp_item_class = (SPItemClass *) klass;
91
92
	parent_class = (SPGroupClass *)g_type_class_ref (SP_TYPE_GROUP);
93
94
	sp_object_class->build = sp_marker_build;
95
	sp_object_class->release = sp_marker_release;
96
	sp_object_class->set = sp_marker_set;
97
	sp_object_class->update = sp_marker_update;
98
	sp_object_class->write = sp_marker_write;
99
100
	sp_item_class->show = sp_marker_private_show;
101
	sp_item_class->hide = sp_marker_private_hide;
102
	sp_item_class->bbox = sp_marker_bbox;
103
	sp_item_class->print = sp_marker_print;
104
}
105
106
/**
107
 * Initializes an SPMarker object.  This notes the marker's viewBox is
108
 * not set and initializes the marker's c2p identity matrix.
109
 */
110
static void
111
sp_marker_init (SPMarker *marker)
112
{
7075 by johanengelen
2geomify marker viewbox
113
    marker->viewBox = Geom::OptRect();
114
    marker->c2p.setIdentity();
7074 by johanengelen
a bit more cleanup
115
    marker->views = NULL;
2077 by bryce
Renaming sp-marker.* to marker.*
116
}
117
118
/**
119
 * Virtual build callback for SPMarker.
120
 *
121
 * This is to be invoked immediately after creation of an SPMarker.  This
122
 * method fills an SPMarker object with its SVG attributes, and calls the
4043 by joncruz
warning cleanup
123
 * parent class' build routine to attach the object to its document and
2077 by bryce
Renaming sp-marker.* to marker.*
124
 * repr.  The result will be creation of the whole document tree.
125
 *
126
 * \see sp_object_build()
127
 */
128
static void
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
129
sp_marker_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
2077 by bryce
Renaming sp-marker.* to marker.*
130
{
131
	SPGroup *group;
132
	SPMarker *marker;
133
134
	group = (SPGroup *) object;
135
	marker = (SPMarker *) object;
136
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
137
	object->readAttr( "markerUnits" );
138
	object->readAttr( "refX" );
139
	object->readAttr( "refY" );
140
	object->readAttr( "markerWidth" );
141
	object->readAttr( "markerHeight" );
142
	object->readAttr( "orient" );
143
	object->readAttr( "viewBox" );
144
	object->readAttr( "preserveAspectRatio" );
2077 by bryce
Renaming sp-marker.* to marker.*
145
146
	if (((SPObjectClass *) parent_class)->build)
147
		((SPObjectClass *) parent_class)->build (object, document, repr);
148
}
149
150
/**
151
 * Removes, releases and unrefs all children of object
152
 *
153
 * This is the inverse of sp_marker_build().  It must be invoked as soon
154
 * as the marker is removed from the tree, even if it is still referenced
155
 * by other objects.  It hides and removes any views of the marker, then
156
 * calls the parent classes' release function to deregister the object
157
 * and release its SPRepr bindings.  The result will be the destruction
158
 * of the entire document tree.
159
 *
160
 * \see sp_object_release()
161
 */
162
static void
163
sp_marker_release (SPObject *object)
164
{
165
	SPMarker *marker;
166
167
	marker = (SPMarker *) object;
168
169
	while (marker->views) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
170
		/* Destroy all DrawingItems etc. */
2077 by bryce
Renaming sp-marker.* to marker.*
171
		/* Parent class ::hide method */
172
		((SPItemClass *) parent_class)->hide ((SPItem *) marker, marker->views->key);
173
		sp_marker_view_remove (marker, marker->views, TRUE);
174
	}
175
176
	if (((SPObjectClass *) parent_class)->release)
177
		((SPObjectClass *) parent_class)->release (object);
178
}
179
180
/**
181
 * Sets an attribute, 'key', of a marker object to 'value'.  Supported
182
 * attributes that can be set with this routine include:
183
 *
184
 *     SP_ATTR_MARKERUNITS
185
 *     SP_ATTR_REFX
186
 *     SP_ATTR_REFY
187
 *     SP_ATTR_MARKERWIDTH
188
 *     SP_ATTR_MARKERHEIGHT
189
 *     SP_ATTR_ORIENT
190
 *     SP_ATTR_VIEWBOX
191
 *     SP_ATTR_PRESERVEASPECTRATIO
192
 */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
193
static void sp_marker_set(SPObject *object, unsigned int key, const gchar *value)
2077 by bryce
Renaming sp-marker.* to marker.*
194
{
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
195
	SPMarker *marker = SP_MARKER(object);
2077 by bryce
Renaming sp-marker.* to marker.*
196
197
	switch (key) {
198
	case SP_ATTR_MARKERUNITS:
199
		marker->markerUnits_set = FALSE;
200
		marker->markerUnits = SP_MARKER_UNITS_STROKEWIDTH;
201
		if (value) {
202
			if (!strcmp (value, "strokeWidth")) {
203
				marker->markerUnits_set = TRUE;
204
			} else if (!strcmp (value, "userSpaceOnUse")) {
205
				marker->markerUnits = SP_MARKER_UNITS_USERSPACEONUSE;
206
				marker->markerUnits_set = TRUE;
207
			}
208
		}
209
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
210
		break;
211
	case SP_ATTR_REFX:
212
	        marker->refX.readOrUnset(value);
213
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
214
		break;
215
	case SP_ATTR_REFY:
216
	        marker->refY.readOrUnset(value);
217
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
218
		break;
219
	case SP_ATTR_MARKERWIDTH:
220
	        marker->markerWidth.readOrUnset(value, SVGLength::NONE, 3.0, 3.0);
221
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
222
		break;
223
	case SP_ATTR_MARKERHEIGHT:
224
	        marker->markerHeight.readOrUnset(value, SVGLength::NONE, 3.0, 3.0);
225
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
226
		break;
227
	case SP_ATTR_ORIENT:
228
		marker->orient_set = FALSE;
229
		marker->orient_auto = FALSE;
230
		marker->orient = 0.0;
231
		if (value) {
232
			if (!strcmp (value, "auto")) {
233
				marker->orient_auto = TRUE;
234
				marker->orient_set = TRUE;
235
			} else if (sp_svg_number_read_f (value, &marker->orient)) {
236
				marker->orient_set = TRUE;
237
			}
238
		}
239
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
240
		break;
241
	case SP_ATTR_VIEWBOX:
7075 by johanengelen
2geomify marker viewbox
242
        marker->viewBox = Geom::OptRect();
2077 by bryce
Renaming sp-marker.* to marker.*
243
		if (value) {
244
			double x, y, width, height;
245
			char *eptr;
246
			/* fixme: We have to take original item affine into account */
247
			/* fixme: Think (Lauris) */
248
			eptr = (gchar *) value;
249
			x = g_ascii_strtod (eptr, &eptr);
250
			while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
251
			y = g_ascii_strtod (eptr, &eptr);
252
			while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
253
			width = g_ascii_strtod (eptr, &eptr);
254
			while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
255
			height = g_ascii_strtod (eptr, &eptr);
256
			while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
257
			if ((width > 0) && (height > 0)) {
258
				/* Set viewbox */
7075 by johanengelen
2geomify marker viewbox
259
                marker->viewBox = Geom::Rect( Geom::Point(x,y),
260
                                              Geom::Point(x + width, y + height) );
2077 by bryce
Renaming sp-marker.* to marker.*
261
			}
262
		}
263
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
264
		break;
265
	case SP_ATTR_PRESERVEASPECTRATIO:
266
		/* Do setup before, so we can use break to escape */
267
		marker->aspect_set = FALSE;
268
		marker->aspect_align = SP_ASPECT_NONE;
269
		marker->aspect_clip = SP_ASPECT_MEET;
270
		object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
271
		if (value) {
272
			int len;
273
			gchar c[256];
274
			const gchar *p, *e;
275
			unsigned int align, clip;
276
			p = value;
277
			while (*p && *p == 32) p += 1;
278
			if (!*p) break;
279
			e = p;
280
			while (*e && *e != 32) e += 1;
281
			len = e - p;
282
			if (len > 8) break;
283
			memcpy (c, value, len);
284
			c[len] = 0;
285
			/* Now the actual part */
286
			if (!strcmp (c, "none")) {
287
				align = SP_ASPECT_NONE;
288
			} else if (!strcmp (c, "xMinYMin")) {
289
				align = SP_ASPECT_XMIN_YMIN;
290
			} else if (!strcmp (c, "xMidYMin")) {
291
				align = SP_ASPECT_XMID_YMIN;
292
			} else if (!strcmp (c, "xMaxYMin")) {
293
				align = SP_ASPECT_XMAX_YMIN;
294
			} else if (!strcmp (c, "xMinYMid")) {
295
				align = SP_ASPECT_XMIN_YMID;
296
			} else if (!strcmp (c, "xMidYMid")) {
297
				align = SP_ASPECT_XMID_YMID;
6990 by speleo3
typo in xMaxYMid
298
			} else if (!strcmp (c, "xMaxYMid")) {
2077 by bryce
Renaming sp-marker.* to marker.*
299
				align = SP_ASPECT_XMAX_YMID;
300
			} else if (!strcmp (c, "xMinYMax")) {
301
				align = SP_ASPECT_XMIN_YMAX;
302
			} else if (!strcmp (c, "xMidYMax")) {
303
				align = SP_ASPECT_XMID_YMAX;
304
			} else if (!strcmp (c, "xMaxYMax")) {
305
				align = SP_ASPECT_XMAX_YMAX;
306
			} else {
307
				break;
308
			}
309
			clip = SP_ASPECT_MEET;
310
			while (*e && *e == 32) e += 1;
6988 by speleo3
bug #166885 (preserveAspectRatio="none" misinterpreted)
311
			if (*e) {
2077 by bryce
Renaming sp-marker.* to marker.*
312
				if (!strcmp (e, "meet")) {
313
					clip = SP_ASPECT_MEET;
314
				} else if (!strcmp (e, "slice")) {
315
					clip = SP_ASPECT_SLICE;
316
				} else {
317
					break;
318
				}
319
			}
320
			marker->aspect_set = TRUE;
321
			marker->aspect_align = align;
322
			marker->aspect_clip = clip;
323
		}
324
		break;
325
	default:
326
		if (((SPObjectClass *) parent_class)->set)
327
			((SPObjectClass *) parent_class)->set (object, key, value);
328
		break;
329
	}
330
}
331
332
/**
333
 * Updates <marker> when its attributes have changed.  Takes care of setting up
334
 * transformations and viewBoxes.
335
 */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
336
static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags)
2077 by bryce
Renaming sp-marker.* to marker.*
337
{
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
338
	SPMarker *marker = SP_MARKER(object);
2077 by bryce
Renaming sp-marker.* to marker.*
339
	SPItemCtx rctx;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
340
        Geom::Rect vb;
2077 by bryce
Renaming sp-marker.* to marker.*
341
	double x, y, width, height;
342
343
	/* fixme: We have to set up clip here too */
344
345
	/* Copy parent context */
346
	rctx.ctx = *ctx;
347
	/* Initialize tranformations */
7032 by verbalshadow
More NR ==> Geom changes
348
	rctx.i2doc = Geom::identity();
349
	rctx.i2vp = Geom::identity();
2077 by bryce
Renaming sp-marker.* to marker.*
350
	/* Set up viewport */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
351
	rctx.viewport = Geom::Rect::from_xywh(0, 0, marker->markerWidth.computed, marker->markerHeight.computed);
2077 by bryce
Renaming sp-marker.* to marker.*
352
353
	/* Start with identity transform */
6839 by cilix42
Next roud of NR ==> Geom conversion
354
	marker->c2p.setIdentity();
2077 by bryce
Renaming sp-marker.* to marker.*
355
356
	/* Viewbox is always present, either implicitly or explicitly */
7075 by johanengelen
2geomify marker viewbox
357
    if (marker->viewBox) {
358
        vb = *marker->viewBox;
2077 by bryce
Renaming sp-marker.* to marker.*
359
	} else {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
360
        vb = rctx.viewport;
2077 by bryce
Renaming sp-marker.* to marker.*
361
	}
362
	/* Now set up viewbox transformation */
363
	/* Determine actual viewbox in viewport coordinates */
364
	if (marker->aspect_align == SP_ASPECT_NONE) {
365
		x = 0.0;
366
		y = 0.0;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
367
		width = rctx.viewport.width();
368
		height = rctx.viewport.height();
2077 by bryce
Renaming sp-marker.* to marker.*
369
	} else {
370
		double scalex, scaley, scale;
371
		/* Things are getting interesting */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
372
        scalex = rctx.viewport.width() / (vb.width());
373
        scaley = rctx.viewport.height() / (vb.height());
2077 by bryce
Renaming sp-marker.* to marker.*
374
		scale = (marker->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley);
7075 by johanengelen
2geomify marker viewbox
375
        width = (vb.width()) * scale;
376
        height = (vb.height()) * scale;
2077 by bryce
Renaming sp-marker.* to marker.*
377
		/* Now place viewbox to requested position */
378
		switch (marker->aspect_align) {
379
		case SP_ASPECT_XMIN_YMIN:
380
			x = 0.0;
381
			y = 0.0;
382
			break;
383
		case SP_ASPECT_XMID_YMIN:
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
384
			x = 0.5 * (rctx.viewport.width() - width);
2077 by bryce
Renaming sp-marker.* to marker.*
385
			y = 0.0;
386
			break;
387
		case SP_ASPECT_XMAX_YMIN:
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
388
			x = 1.0 * (rctx.viewport.width() - width);
2077 by bryce
Renaming sp-marker.* to marker.*
389
			y = 0.0;
390
			break;
391
		case SP_ASPECT_XMIN_YMID:
392
			x = 0.0;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
393
			y = 0.5 * (rctx.viewport.height() - height);
2077 by bryce
Renaming sp-marker.* to marker.*
394
			break;
395
		case SP_ASPECT_XMID_YMID:
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
396
			x = 0.5 * (rctx.viewport.width() - width);
397
			y = 0.5 * (rctx.viewport.height() - height);
2077 by bryce
Renaming sp-marker.* to marker.*
398
			break;
399
		case SP_ASPECT_XMAX_YMID:
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
400
			x = 1.0 * (rctx.viewport.width() - width);
401
			y = 0.5 * (rctx.viewport.height() - height);
2077 by bryce
Renaming sp-marker.* to marker.*
402
			break;
403
		case SP_ASPECT_XMIN_YMAX:
404
			x = 0.0;
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
405
			y = 1.0 * (rctx.viewport.height() - height);
2077 by bryce
Renaming sp-marker.* to marker.*
406
			break;
407
		case SP_ASPECT_XMID_YMAX:
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
408
			x = 0.5 * (rctx.viewport.width() - width);
409
			y = 1.0 * (rctx.viewport.height() - height);
2077 by bryce
Renaming sp-marker.* to marker.*
410
			break;
411
		case SP_ASPECT_XMAX_YMAX:
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
412
			x = 1.0 * (rctx.viewport.width() - width);
413
			y = 1.0 * (rctx.viewport.height() - height);
2077 by bryce
Renaming sp-marker.* to marker.*
414
			break;
415
		default:
416
			x = 0.0;
417
			y = 0.0;
418
			break;
419
		}
420
	}
421
8836 by speleo3
fix bug 168663, marker shifted wrong by viewBox
422
	// viewbox transformation and reference translation
423
	marker->c2p = Geom::Translate(-marker->refX.computed, -marker->refY.computed) *
424
		Geom::Scale(width / vb.width(), height / vb.height());
2077 by bryce
Renaming sp-marker.* to marker.*
425
426
	rctx.i2doc = marker->c2p * rctx.i2doc;
427
428
	/* If viewBox is set reinitialize child viewport */
429
	/* Otherwise it already correct */
7075 by johanengelen
2geomify marker viewbox
430
	if (marker->viewBox) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
431
	    rctx.viewport = *marker->viewBox;
6839 by cilix42
Next roud of NR ==> Geom conversion
432
            rctx.i2vp = Geom::identity();
2077 by bryce
Renaming sp-marker.* to marker.*
433
	}
434
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
435
	// And invoke parent method
436
	if (((SPObjectClass *) (parent_class))->update) {
2077 by bryce
Renaming sp-marker.* to marker.*
437
		((SPObjectClass *) (parent_class))->update (object, (SPCtx *) &rctx, flags);
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
438
        }
2077 by bryce
Renaming sp-marker.* to marker.*
439
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
440
        // As last step set additional transform of drawing group
441
        for (SPMarkerView *v = marker->views; v != NULL; v = v->next) {
442
            for (unsigned i = 0 ; i < v->items.size() ; i++) {
6839 by cilix42
Next roud of NR ==> Geom conversion
443
                if (v->items[i]) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
444
                    Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[i]);
445
                    g->setChildTransform(marker->c2p);
6839 by cilix42
Next roud of NR ==> Geom conversion
446
                }
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
447
            }
448
        }
2077 by bryce
Renaming sp-marker.* to marker.*
449
}
450
4043 by joncruz
warning cleanup
451
/**
2077 by bryce
Renaming sp-marker.* to marker.*
452
 * Writes the object's properties into its repr object.
453
 */
454
static Inkscape::XML::Node *
5884 by mental
plumb XML::Documents in everywhere
455
sp_marker_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
2077 by bryce
Renaming sp-marker.* to marker.*
456
{
457
	SPMarker *marker;
458
459
	marker = SP_MARKER (object);
460
461
	if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
2253 by mental
start switching sp_repr_new* over to XML::Document::create*, and rename create methods to match DOM
462
		repr = xml_doc->createElement("svg:marker");
2077 by bryce
Renaming sp-marker.* to marker.*
463
	}
464
465
	if (marker->markerUnits_set) {
466
		if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
467
			repr->setAttribute("markerUnits", "strokeWidth");
468
		} else {
469
			repr->setAttribute("markerUnits", "userSpaceOnUse");
470
		}
471
	} else {
472
		repr->setAttribute("markerUnits", NULL);
473
	}
474
	if (marker->refX._set) {
475
		sp_repr_set_svg_double(repr, "refX", marker->refX.computed);
476
	} else {
477
		repr->setAttribute("refX", NULL);
478
	}
479
	if (marker->refY._set) {
480
		sp_repr_set_svg_double (repr, "refY", marker->refY.computed);
481
	} else {
482
		repr->setAttribute("refY", NULL);
483
	}
484
	if (marker->markerWidth._set) {
485
		sp_repr_set_svg_double (repr, "markerWidth", marker->markerWidth.computed);
486
	} else {
487
		repr->setAttribute("markerWidth", NULL);
488
	}
489
	if (marker->markerHeight._set) {
490
		sp_repr_set_svg_double (repr, "markerHeight", marker->markerHeight.computed);
491
	} else {
492
		repr->setAttribute("markerHeight", NULL);
493
	}
494
	if (marker->orient_set) {
495
		if (marker->orient_auto) {
496
			repr->setAttribute("orient", "auto");
497
		} else {
498
			sp_repr_set_css_double(repr, "orient", marker->orient);
499
		}
500
	} else {
501
		repr->setAttribute("orient", NULL);
502
	}
503
	/* fixme: */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
504
	//XML Tree being used directly here while it shouldn't be....
505
	repr->setAttribute("viewBox", object->getRepr()->attribute("viewBox"));
506
	//XML Tree being used directly here while it shouldn't be....
507
	repr->setAttribute("preserveAspectRatio", object->getRepr()->attribute("preserveAspectRatio"));
2077 by bryce
Renaming sp-marker.* to marker.*
508
509
	if (((SPObjectClass *) (parent_class))->write)
5884 by mental
plumb XML::Documents in everywhere
510
		((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
2077 by bryce
Renaming sp-marker.* to marker.*
511
512
	return repr;
513
}
514
515
/**
516
 * This routine is disabled to break propagation.
517
 */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
518
static Inkscape::DrawingItem *
519
sp_marker_private_show (SPItem */*item*/, Inkscape::Drawing &/*drawing*/, unsigned int /*key*/, unsigned int /*flags*/)
2077 by bryce
Renaming sp-marker.* to marker.*
520
{
4043 by joncruz
warning cleanup
521
    /* Break propagation */
522
    return NULL;
2077 by bryce
Renaming sp-marker.* to marker.*
523
}
524
525
/**
526
 * This routine is disabled to break propagation.
527
 */
528
static void
4043 by joncruz
warning cleanup
529
sp_marker_private_hide (SPItem */*item*/, unsigned int /*key*/)
2077 by bryce
Renaming sp-marker.* to marker.*
530
{
4043 by joncruz
warning cleanup
531
    /* Break propagation */
2077 by bryce
Renaming sp-marker.* to marker.*
532
}
533
534
/**
535
 * This routine is disabled to break propagation.
536
 */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
537
static Geom::OptRect
538
sp_marker_bbox(SPItem const *, Geom::Affine const &, SPItem::BBoxType)
2077 by bryce
Renaming sp-marker.* to marker.*
539
{
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
540
    /* Break propagation */
541
    return Geom::OptRect();
2077 by bryce
Renaming sp-marker.* to marker.*
542
}
543
544
/**
545
 * This routine is disabled to break propagation.
546
 */
547
static void
4043 by joncruz
warning cleanup
548
sp_marker_print (SPItem */*item*/, SPPrintContext */*ctx*/)
2077 by bryce
Renaming sp-marker.* to marker.*
549
{
4043 by joncruz
warning cleanup
550
    /* Break propagation */
2077 by bryce
Renaming sp-marker.* to marker.*
551
}
552
553
/* fixme: Remove link if zero-sized (Lauris) */
554
555
/**
556
 * Removes any SPMarkerViews that a marker has with a specific key.
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
557
 * Set up the DrawingItem array's size in the specified SPMarker's SPMarkerView.
2077 by bryce
Renaming sp-marker.* to marker.*
558
 * This is called from sp_shape_update() for shapes that have markers.  It
559
 * removes the old view of the marker and establishes a new one, registering
560
 * it with the marker's list of views for future updates.
4043 by joncruz
warning cleanup
561
 *
2077 by bryce
Renaming sp-marker.* to marker.*
562
 * \param marker Marker to create views in.
563
 * \param key Key to give each SPMarkerView.
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
564
 * \param size Number of DrawingItems to put in the SPMarkerView.
2077 by bryce
Renaming sp-marker.* to marker.*
565
 */
566
void
567
sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
568
{
7071 by johanengelen
clean up code a bit. especially remove obscure newing of a struct with C++ objects.
569
    SPMarkerView *view;
570
    unsigned int i;
2077 by bryce
Renaming sp-marker.* to marker.*
571
7071 by johanengelen
clean up code a bit. especially remove obscure newing of a struct with C++ objects.
572
    for (view = marker->views; view != NULL; view = view->next) {
573
        if (view->key == key) break;
574
    }
575
    if (view && (view->items.size() != size)) {
576
        /* Free old view and allocate new */
577
        /* Parent class ::hide method */
578
        ((SPItemClass *) parent_class)->hide ((SPItem *) marker, key);
579
        sp_marker_view_remove (marker, view, TRUE);
580
        view = NULL;
581
    }
582
    if (!view) {
583
        view = new SPMarkerView();
584
        view->items.clear();
585
        for (i = 0; i < size; i++) {
586
            view->items.push_back(NULL);
587
        }
588
        view->next = marker->views;
589
        marker->views = view;
590
        view->key = key;
591
    }
2077 by bryce
Renaming sp-marker.* to marker.*
592
}
593
4043 by joncruz
warning cleanup
594
/**
2077 by bryce
Renaming sp-marker.* to marker.*
595
 * Shows an instance of a marker.  This is called during sp_shape_update_marker_view()
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
596
 * show and transform a child item in the drawing for all views with the given key.
2077 by bryce
Renaming sp-marker.* to marker.*
597
 */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
598
Inkscape::DrawingItem *
599
sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent,
6007 by johanengelen
2geomify sp_shape_update_marker_view.
600
                          unsigned int key, unsigned int pos,
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
601
                          Geom::Affine const &base, float linewidth)
2077 by bryce
Renaming sp-marker.* to marker.*
602
{
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
603
    // do not show marker if linewidth == 0 and markerUnits == strokeWidth
604
    // otherwise Cairo will fail to render anything on the tile
605
    // that contains the "degenerate" marker
606
    if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH && linewidth == 0) {
607
        return NULL;
608
    }
609
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
610
    for (SPMarkerView *v = marker->views; v != NULL; v = v->next) {
611
        if (v->key == key) {
6885 by Ted Gould
From trunk
612
            if (pos >= v->items.size()) {
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
613
                return NULL;
614
            }
615
            if (!v->items[pos]) {
616
                /* Parent class ::show method */
617
                v->items[pos] = ((SPItemClass *) parent_class)->show ((SPItem *) marker,
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
618
                                                                      parent->drawing(), key,
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
619
                                                                      SP_ITEM_REFERENCE_FLAGS);
620
                if (v->items[pos]) {
621
                    /* fixme: Position (Lauris) */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
622
                    parent->prependChild(v->items[pos]);
623
                    Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[pos]);
624
                    if (g) g->setChildTransform(marker->c2p);
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
625
                }
626
            }
627
            if (v->items[pos]) {
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
628
                Geom::Affine m;
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
629
                if (marker->orient_auto) {
630
                    m = base;
631
                } else {
632
                    /* fixme: Orient units (Lauris) */
7071 by johanengelen
clean up code a bit. especially remove obscure newing of a struct with C++ objects.
633
                    m = Geom::Rotate::from_degrees(marker->orient);
634
                    m *= Geom::Translate(base.translation());
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
635
                }
636
                if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
637
                    m = Geom::Scale(linewidth) * m;
638
                }
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
639
                v->items[pos]->setTransform(m);
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
640
            }
641
            return v->items[pos];
642
        }
643
    }
644
645
    return NULL;
2077 by bryce
Renaming sp-marker.* to marker.*
646
}
647
648
/**
649
 * Hides/removes all views of the given marker that have key 'key'.
650
 * This replaces SPItem implementation because we have our own views
651
 * \param key SPMarkerView key to hide.
652
 */
653
void
654
sp_marker_hide (SPMarker *marker, unsigned int key)
655
{
656
	SPMarkerView *v;
657
658
	v = marker->views;
659
	while (v != NULL) {
660
		SPMarkerView *next;
661
		next = v->next;
662
		if (v->key == key) {
663
			/* Parent class ::hide method */
664
			((SPItemClass *) parent_class)->hide ((SPItem *) marker, key);
665
			sp_marker_view_remove (marker, v, TRUE);
666
			return;
667
		}
668
		v = next;
669
	}
670
}
671
672
/**
4043 by joncruz
warning cleanup
673
 * Removes a given view.  Also will destroy sub-items in the view if destroyitems
2077 by bryce
Renaming sp-marker.* to marker.*
674
 * is set to a non-zero value.
675
 */
676
static void
677
sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems)
678
{
679
	unsigned int i;
680
	if (view == marker->views) {
681
		marker->views = view->next;
682
	} else {
683
		SPMarkerView *v;
684
		for (v = marker->views; v->next != view; v = v->next) if (!v->next) return;
685
		v->next = view->next;
686
	}
687
	if (destroyitems) {
6885 by Ted Gould
From trunk
688
      for (i = 0; i < view->items.size(); i++) {
2077 by bryce
Renaming sp-marker.* to marker.*
689
			/* We have to walk through the whole array because there may be hidden items */
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
690
			delete view->items[i];
2077 by bryce
Renaming sp-marker.* to marker.*
691
		}
692
	}
7074 by johanengelen
a bit more cleanup
693
    view->items.clear();
694
    delete view;
2077 by bryce
Renaming sp-marker.* to marker.*
695
}
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
696
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
697
const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine /*transform*/, Geom::Affine move)
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
698
{
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
699
    Inkscape::XML::Document *xml_doc = document->getReprDoc();
700
    Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
701
702
    Inkscape::XML::Node *repr = xml_doc->createElement("svg:marker");
4724 by buliabyak
fix scaling with stroke width for user-created markers
703
704
    // Uncommenting this will make the marker fixed-size independent of stroke width.
705
    // Commented out for consistency with standard markers which scale when you change
706
    // stroke width:
707
    //repr->setAttribute("markerUnits", "userSpaceOnUse");
708
6885 by Ted Gould
From trunk
709
    sp_repr_set_svg_double(repr, "markerWidth", bounds.dimensions()[Geom::X]);
710
    sp_repr_set_svg_double(repr, "markerHeight", bounds.dimensions()[Geom::Y]);
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
711
712
    repr->setAttribute("orient", "auto");
713
714
    defsrepr->appendChild(repr);
715
    const gchar *mark_id = repr->attribute("id");
716
    SPObject *mark_object = document->getObjectById(mark_id);
717
718
    for (GSList *i = reprs; i != NULL; i = i->next) {
719
            Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data);
720
        SPItem *copy = SP_ITEM(mark_object->appendChildRepr(node));
721
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
722
        Geom::Affine dup_transform;
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
723
        if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform))
6839 by cilix42
Next roud of NR ==> Geom conversion
724
            dup_transform = Geom::identity();
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
725
        dup_transform *= move;
726
9020 by JazzyNico
Code refactoring and merging with trunk (revision 10599).
727
        copy->doWriteTransform(copy->getRepr(), dup_transform);
3864 by johanengelen
apply John Cliff's patch [ 1743843 ] Create Marker from Selection Menu Item
728
    }
729
730
    Inkscape::GC::release(repr);
731
    return mark_id;
732
}
6836 by cilix42
More NR ==> Geom conversion (points and some matrices/transforms)
733
734
/*
735
  Local Variables:
736
  mode:c++
737
  c-file-style:"stroustrup"
738
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
739
  indent-tabs-mode:nil
740
  fill-column:99
741
  End:
742
*/
743
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :