~vaifrax/inkscape/bugfix170049

« back to all changes in this revision

Viewing changes to src/sp-line.cpp

  • Committer: mental
  • Date: 2006-01-16 02:36:01 UTC
  • Revision ID: mental@users.sourceforge.net-20060116023601-wkr0h7edl5veyudq
moving trunk for module inkscape

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define __SP_LINE_C__
 
2
 
 
3
/*
 
4
 * SVG <line> implementation
 
5
 *
 
6
 * Authors:
 
7
 *   Lauris Kaplinski <lauris@kaplinski.com>
 
8
 *
 
9
 * Copyright (C) 1999-2002 Lauris Kaplinski
 
10
 *
 
11
 * Released under GNU GPL, read the file 'COPYING' for more information
 
12
 */
 
13
 
 
14
#ifdef HAVE_CONFIG_H
 
15
# include <config.h>
 
16
#endif
 
17
#include "attributes.h"
 
18
#include "style.h"
 
19
#include "sp-line.h"
 
20
#include "display/curve.h"
 
21
#include <glibmm/i18n.h>
 
22
#include <libnr/nr-matrix-fns.h>
 
23
#include <xml/repr.h>
 
24
 
 
25
static void sp_line_class_init (SPLineClass *klass);
 
26
static void sp_line_init (SPLine *line);
 
27
 
 
28
static void sp_line_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr);
 
29
static void sp_line_set (SPObject *object, unsigned int key, const gchar *value);
 
30
static Inkscape::XML::Node *sp_line_write (SPObject *object, Inkscape::XML::Node *repr, guint flags);
 
31
 
 
32
static gchar *sp_line_description (SPItem * item);
 
33
static NR::Matrix sp_line_set_transform(SPItem *item, NR::Matrix const &xform);
 
34
 
 
35
static void sp_line_update (SPObject *object, SPCtx *ctx, guint flags);
 
36
static void sp_line_set_shape (SPShape *shape);
 
37
 
 
38
static SPShapeClass *parent_class;
 
39
 
 
40
GType
 
41
sp_line_get_type (void)
 
42
{
 
43
        static GType line_type = 0;
 
44
 
 
45
        if (!line_type) {
 
46
                GTypeInfo line_info = {
 
47
                        sizeof (SPLineClass),
 
48
                        NULL,   /* base_init */
 
49
                        NULL,   /* base_finalize */
 
50
                        (GClassInitFunc) sp_line_class_init,
 
51
                        NULL,   /* klass_finalize */
 
52
                        NULL,   /* klass_data */
 
53
                        sizeof (SPLine),
 
54
                        16,     /* n_preallocs */
 
55
                        (GInstanceInitFunc) sp_line_init,
 
56
                        NULL,   /* value_table */
 
57
                };
 
58
                line_type = g_type_register_static (SP_TYPE_SHAPE, "SPLine", &line_info, (GTypeFlags)0);
 
59
        }
 
60
        return line_type;
 
61
}
 
62
 
 
63
static void
 
64
sp_line_class_init (SPLineClass *klass)
 
65
{
 
66
        parent_class = (SPShapeClass *) g_type_class_ref (SP_TYPE_SHAPE);
 
67
 
 
68
        SPObjectClass *sp_object_class = (SPObjectClass *) klass;
 
69
        sp_object_class->build = sp_line_build;
 
70
        sp_object_class->set = sp_line_set;
 
71
        sp_object_class->write = sp_line_write;
 
72
 
 
73
        SPItemClass *item_class = (SPItemClass *) klass;
 
74
        item_class->description = sp_line_description;
 
75
        item_class->set_transform = sp_line_set_transform;
 
76
 
 
77
        sp_object_class->update = sp_line_update;
 
78
 
 
79
        SPShapeClass *shape_class = (SPShapeClass *) klass;
 
80
        shape_class->set_shape = sp_line_set_shape;
 
81
}
 
82
 
 
83
static void
 
84
sp_line_init (SPLine * line)
 
85
{
 
86
        line->x1.unset();
 
87
        line->y1.unset();
 
88
        line->x2.unset();
 
89
        line->y2.unset();
 
90
}
 
91
 
 
92
 
 
93
static void
 
94
sp_line_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr)
 
95
{
 
96
        if (((SPObjectClass *) parent_class)->build) {
 
97
                ((SPObjectClass *) parent_class)->build (object, document, repr);
 
98
        }
 
99
 
 
100
        sp_object_read_attr (object, "x1");
 
101
        sp_object_read_attr (object, "y1");
 
102
        sp_object_read_attr (object, "x2");
 
103
        sp_object_read_attr (object, "y2");
 
104
}
 
105
 
 
106
static void
 
107
sp_line_set (SPObject *object, unsigned int key, const gchar *value)
 
108
{
 
109
        SPLine * line = SP_LINE (object);
 
110
 
 
111
        /* fixme: we should really collect updates */
 
112
 
 
113
        switch (key) {
 
114
        case SP_ATTR_X1:
 
115
                line->x1.readOrUnset(value);
 
116
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
117
                break;
 
118
        case SP_ATTR_Y1:
 
119
                line->y1.readOrUnset(value);
 
120
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
121
                break;
 
122
        case SP_ATTR_X2:
 
123
                line->x2.readOrUnset(value);
 
124
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
125
                break;
 
126
        case SP_ATTR_Y2:
 
127
                line->y2.readOrUnset(value);
 
128
                object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
129
                break;
 
130
        default:
 
131
                if (((SPObjectClass *) parent_class)->set)
 
132
                        ((SPObjectClass *) parent_class)->set (object, key, value);
 
133
                break;
 
134
        }
 
135
}
 
136
 
 
137
static void
 
138
sp_line_update (SPObject *object, SPCtx *ctx, guint flags)
 
139
{
 
140
        if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
 
141
                SPLine *line = SP_LINE (object);
 
142
 
 
143
                SPStyle const *style = object->style;
 
144
                double const d = 1.0 / NR::expansion(((SPItemCtx const *) ctx)->i2vp);
 
145
                double const em = style->font_size.computed;
 
146
                double const ex = em * 0.5;  // fixme: get from pango or libnrtype.
 
147
                line->x1.update(em, ex, d);
 
148
                line->x2.update(em, ex, d);
 
149
                line->y1.update(em, ex, d);
 
150
                line->y2.update(em, ex, d);
 
151
 
 
152
                sp_shape_set_shape ((SPShape *) object);
 
153
        }
 
154
 
 
155
        if (((SPObjectClass *) parent_class)->update)
 
156
                ((SPObjectClass *) parent_class)->update (object, ctx, flags);
 
157
}
 
158
 
 
159
 
 
160
static Inkscape::XML::Node *
 
161
sp_line_write (SPObject *object, Inkscape::XML::Node *repr, guint flags)
 
162
{
 
163
        SPLine *line  = SP_LINE (object);
 
164
 
 
165
        if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
 
166
                repr = sp_repr_new ("svg:line");
 
167
        }
 
168
 
 
169
        if (repr != SP_OBJECT_REPR (object)) {
 
170
                repr->mergeFrom(SP_OBJECT_REPR (object), "id");
 
171
        }
 
172
 
 
173
        sp_repr_set_svg_double(repr, "x1", line->x1.computed);
 
174
        sp_repr_set_svg_double(repr, "y1", line->y1.computed);
 
175
        sp_repr_set_svg_double(repr, "x2", line->x2.computed);
 
176
        sp_repr_set_svg_double(repr, "y2", line->y2.computed);
 
177
 
 
178
        if (((SPObjectClass *) (parent_class))->write)
 
179
                ((SPObjectClass *) (parent_class))->write (object, repr, flags);
 
180
 
 
181
        return repr;
 
182
}
 
183
 
 
184
static gchar *
 
185
sp_line_description(SPItem *item)
 
186
{
 
187
        return g_strdup(_("<b>Line</b>"));
 
188
}
 
189
 
 
190
static NR::Matrix
 
191
sp_line_set_transform (SPItem *item, NR::Matrix const &xform)
 
192
{
 
193
        SPLine *line = SP_LINE (item);
 
194
        NR::Point points[2];
 
195
 
 
196
        points[0] = NR::Point(line->x1.computed, line->y1.computed);
 
197
        points[1] = NR::Point(line->x2.computed, line->y2.computed);
 
198
 
 
199
        points[0] *= xform;
 
200
        points[1] *= xform;
 
201
 
 
202
        line->x1.computed = points[0][NR::X];
 
203
        line->y1.computed = points[0][NR::Y];
 
204
        line->x2.computed = points[1][NR::X];
 
205
        line->y2.computed = points[1][NR::Y];
 
206
 
 
207
        sp_item_adjust_stroke(item, NR::expansion(xform));
 
208
 
 
209
        SP_OBJECT (item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
 
210
 
 
211
        return NR::identity();
 
212
}
 
213
 
 
214
static void
 
215
sp_line_set_shape (SPShape *shape)
 
216
{
 
217
        SPLine *line = SP_LINE (shape);
 
218
 
 
219
        SPCurve *c = sp_curve_new ();
 
220
 
 
221
        sp_curve_moveto (c, line->x1.computed, line->y1.computed);
 
222
        sp_curve_lineto (c, line->x2.computed, line->y2.computed);
 
223
 
 
224
        sp_shape_set_curve_insync (shape, c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update
 
225
 
 
226
        sp_curve_unref (c);
 
227
}