1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
#ifndef __SP_ITEM_H__
#define __SP_ITEM_H__
/** \file
* Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx, SPItemClass, SPEvent.
*/
/*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
* Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
*
* Copyright (C) 1999-2006 authors
* Copyright (C) 2001-2002 Ximian, Inc.
* Copyright (C) 2004 Monash University
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include <vector>
#include "display/nr-arena-forward.h"
#include "sp-object.h"
#include <2geom/matrix.h>
#include <libnr/nr-rect.h>
#include <2geom/forward.h>
#include <libnr/nr-convert2geom.h>
#include <snap-preferences.h>
#include "snap-candidate.h"
class SPGuideConstraint;
struct SPClipPathReference;
struct SPMaskReference;
struct SPAvoidRef;
struct SPPrintContext;
namespace Inkscape { class URIReference;}
enum {
SP_EVENT_INVALID,
SP_EVENT_NONE,
SP_EVENT_ACTIVATE,
SP_EVENT_MOUSEOVER,
SP_EVENT_MOUSEOUT
};
/**
* Event structure.
*
* \todo This is just placeholder. Plan:
* We do extensible event structure, that hold applicable (ui, non-ui)
* data pointers. So it is up to given object/arena implementation
* to process correct ones in meaningful way.
* Also, this probably goes to SPObject base class.
*
*/
struct SPEvent {
unsigned int type;
gpointer data;
};
/// SPItemView
struct SPItemView {
SPItemView *next;
unsigned int flags;
unsigned int key;
NRArenaItem *arenaitem;
};
/* flags */
#define SP_ITEM_BBOX_VISUAL 1
#define SP_ITEM_SHOW_DISPLAY (1 << 0)
/**
* Flag for referenced views (i.e. markers, clippaths, masks and patterns);
currently unused, does the same as DISPLAY
*/
#define SP_ITEM_REFERENCE_FLAGS (1 << 1)
/// Contains transformations to document/viewport and the viewport size.
struct SPItemCtx {
SPCtx ctx;
/** Item to document transformation */
Geom::Matrix i2doc;
/** Viewport size */
NRRect vp;
/** Item to viewport transformation */
Geom::Matrix i2vp;
};
/** Abstract base class for all visible shapes. */
struct SPItem : public SPObject {
enum BBoxType {
// legacy behavior: includes crude stroke, markers; excludes long miters, blur margin; is known to be wrong for caps
APPROXIMATE_BBOX,
// includes only the bare path bbox, no stroke, no nothing
GEOMETRIC_BBOX,
// includes everything: correctly done stroke (with proper miters and caps), markers, filter margins (e.g. blur)
RENDERING_BBOX
};
unsigned int sensitive : 1;
unsigned int stop_paint: 1;
double transform_center_x;
double transform_center_y;
Geom::Matrix transform;
SPClipPathReference *clip_ref;
SPMaskReference *mask_ref;
// Used for object-avoiding connectors
SPAvoidRef *avoidRef;
SPItemView *display;
std::vector<SPGuideConstraint> constraints;
sigc::signal<void, Geom::Matrix const *, SPItem *> _transformed_signal;
void init();
bool isLocked() const;
void setLocked(bool lock);
bool isHidden() const;
void setHidden(bool hidden);
bool isEvaluated() const;
void setEvaluated(bool visible);
void resetEvaluated();
bool isHidden(unsigned display_key) const;
bool isExplicitlyHidden() const;
void setExplicitlyHidden(bool val);
void setCenter(Geom::Point object_centre);
void unsetCenter();
bool isCenterSet();
Geom::Point getCenter() const;
bool isVisibleAndUnlocked() const;
bool isVisibleAndUnlocked(unsigned display_key) const;
Geom::Matrix getRelativeTransform(SPObject const *obj) const;
void raiseOne();
void lowerOne();
void raiseToTop();
void lowerToBottom();
Geom::OptRect getBounds(Geom::Matrix const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const;
sigc::connection _clip_ref_connection;
sigc::connection _mask_ref_connection;
sigc::connection connectTransformed(sigc::slot<void, Geom::Matrix const *, SPItem *> slot) {
return _transformed_signal.connect(slot);
}
private:
enum EvaluatedStatus
{
StatusUnknown, StatusCalculated, StatusSet
};
mutable bool _is_evaluated;
mutable EvaluatedStatus _evaluated_status;
};
/// The SPItem vtable.
struct SPItemClass {
SPObjectClass parent_class;
/** BBox union in given coordinate system */
void (* bbox) (SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
/** Printing method. Assumes ctm is set to item affine matrix */
/* \todo Think about it, and maybe implement generic export method instead (Lauris) */
void (* print) (SPItem *item, SPPrintContext *ctx);
/** Give short description of item (for status display) */
gchar * (* description) (SPItem * item);
NRArenaItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
void (* hide) (SPItem *item, unsigned int key);
/** Write to an iterator the points that should be considered for snapping
* as the item's `nodes'.
*/
void (* snappoints) (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
/** Apply the transform optimally, and return any residual transformation */
Geom::Matrix (* set_transform)(SPItem *item, Geom::Matrix const &transform);
/** Convert the item to guidelines */
void (* convert_to_guides)(SPItem *item);
/** Emit event, if applicable */
gint (* event) (SPItem *item, SPEvent *event);
};
/* Flag testing macros */
#define SP_ITEM_STOP_PAINT(i) (SP_ITEM (i)->stop_paint)
/* Methods */
void sp_item_invoke_bbox(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated));
void sp_item_invoke_bbox_full(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear);
void sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) __attribute__ ((deprecated));
unsigned sp_item_pos_in_parent(SPItem *item);
gchar *sp_item_description(SPItem * item);
void sp_item_invoke_print(SPItem *item, SPPrintContext *ctx);
/** Shows/Hides item on given arena display list */
unsigned int sp_item_display_key_new(unsigned int numkeys);
NRArenaItem *sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
void sp_item_invoke_hide(SPItem *item, unsigned int key);
void sp_item_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
void sp_item_adjust_pattern(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
void sp_item_adjust_gradient(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
void sp_item_adjust_stroke(SPItem *item, gdouble ex);
void sp_item_adjust_stroke_width_recursive(SPItem *item, gdouble ex);
void sp_item_adjust_paint_recursive(SPItem *item, Geom::Matrix advertized_transform, Geom::Matrix t_ancestors, bool is_pattern);
void sp_item_adjust_livepatheffect(SPItem *item, Geom::Matrix const &postmul, bool set = false);
void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, Geom::Matrix const &transform, Geom::Matrix const *adv = NULL, bool compensate = true);
void sp_item_set_item_transform(SPItem *item, Geom::Matrix const &transform);
void sp_item_convert_item_to_guides(SPItem *item);
gint sp_item_event (SPItem *item, SPEvent *event);
/* Utility */
NRArenaItem *sp_item_get_arenaitem(SPItem *item, unsigned int key);
void sp_item_bbox_desktop(SPItem *item, NRRect *bbox, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated));
Geom::OptRect sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
Geom::Matrix i2anc_affine(SPObject const *item, SPObject const *ancestor);
Geom::Matrix i2i_affine(SPObject const *src, SPObject const *dest);
Geom::Matrix sp_item_i2doc_affine(SPItem const *item);
/* fixme: - these are evil, but OK */
/* Fill *TRANSFORM with the item-to-desktop transform. See doc/coordinates.txt
* for a description of `Desktop coordinates'; though see also mental's comment
* at the top of that file.
*
* \return TRANSFORM.
*/
Geom::Matrix sp_item_i2d_affine(SPItem const *item);
void sp_item_set_i2d_affine(SPItem *item, Geom::Matrix const &transform);
Geom::Matrix sp_item_dt2i_affine(SPItem const *item);
int sp_item_repr_compare_position(SPItem *first, SPItem *second);
SPItem *sp_item_first_item_child (SPObject *obj);
void sp_item_convert_to_guides(SPItem *item);
#endif
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
|