~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu5

« back to all changes in this revision

Viewing changes to src/dialogs/fill-style.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Wolfram Quester
  • Date: 2004-06-02 10:35:45 UTC
  • Revision ID: james.westby@ubuntu.com-20040602103545-q3x0q6xd2k1yj0fr
Tags: upstream-0.38.1
ImportĀ upstreamĀ versionĀ 0.38.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define __SP_FILL_STYLE_C__
 
2
 
 
3
/**
 
4
 * \brief  Fill style widget
 
5
 *
 
6
 * Authors:
 
7
 *   Lauris Kaplinski <lauris@kaplinski.com>
 
8
 *   Frank Felfe <innerspace@iname.com>
 
9
 *
 
10
 * Copyright (C) 1999-2002 authors
 
11
 * Copyright (C) 2001-2002 Ximian, Inc.
 
12
 *
 
13
 * Released under GNU GPL, read the file 'COPYING' for more information
 
14
 */
 
15
 
 
16
#define noSP_FS_VERBOSE
 
17
 
 
18
#include <config.h>
 
19
 
 
20
#include <string.h>
 
21
#include <gtk/gtksignal.h>
 
22
#include <gtk/gtkmisc.h>
 
23
#include <gtk/gtklabel.h>
 
24
#include <gtk/gtkhbox.h>
 
25
#include <gtk/gtkoptionmenu.h>
 
26
#include <gtk/gtkmenuitem.h>
 
27
#include <gtk/gtkhbox.h>
 
28
#include <gtk/gtklabel.h>
 
29
#include <gtk/gtkoptionmenu.h>
 
30
#include <gtk/gtkmenuitem.h>
 
31
 
 
32
#include <libnr/nr-values.h>
 
33
 
 
34
#include <libart_lgpl/art_svp.h>
 
35
#include <libart_lgpl/art_svp_wind.h>
 
36
 
 
37
#include <libnr/nr-values.h>
 
38
 
 
39
#include <libart_lgpl/art_svp.h>
 
40
#include <libart_lgpl/art_svp_wind.h>
 
41
 
 
42
#include "../helper/sp-intl.h"
 
43
#include "../helper/window.h"
 
44
#include "../svg/svg.h"
 
45
#include "../svg/stringstream.h"
 
46
#include "../widgets/sp-widget.h"
 
47
#include "../sp-gradient.h"
 
48
#include "../widgets/paint-selector.h"
 
49
#include "../style.h"
 
50
#include "../gradient-chemistry.h"
 
51
#include "../document.h"
 
52
#include "../desktop-handles.h"
 
53
#include "../selection.h"
 
54
#include "../sp-item.h"
 
55
#include "../inkscape.h"
 
56
 
 
57
#include "fill-style.h"
 
58
 
 
59
 
 
60
 
 
61
static void sp_fill_style_widget_construct          ( SPWidget *spw, 
 
62
                                                      SPPaintSelector *psel );
 
63
                                                      
 
64
static void sp_fill_style_widget_modify_selection   ( SPWidget *spw, 
 
65
                                                      SPSelection *selection, 
 
66
                                                      guint flags, 
 
67
                                                      SPPaintSelector *psel );
 
68
                                                      
 
69
static void sp_fill_style_widget_change_selection   ( SPWidget *spw, 
 
70
                                                      SPSelection *selection, 
 
71
                                                      SPPaintSelector *psel );
 
72
                                                      
 
73
static void sp_fill_style_widget_attr_changed       ( SPWidget *spw, 
 
74
                                                      const gchar *key, 
 
75
                                                      const gchar *oldval, 
 
76
                                                      const gchar *newval );
 
77
                                                      
 
78
static void sp_fill_style_widget_update             ( SPWidget *spw, 
 
79
                                                      SPSelection *sel );
 
80
                                                      
 
81
static void sp_fill_style_widget_update_repr        ( SPWidget *spw, 
 
82
                                                      SPRepr *repr );
 
83
 
 
84
static void sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel, 
 
85
                                                      SPPaintSelectorMode mode, 
 
86
                                                      SPWidget *spw );
 
87
                                                      
 
88
static void sp_fill_style_widget_paint_dragged      ( SPPaintSelector *psel, 
 
89
                                                      SPWidget *spw );
 
90
                                                      
 
91
static void sp_fill_style_widget_paint_changed      ( SPPaintSelector *psel, 
 
92
                                                      SPWidget *spw );
 
93
 
 
94
static void sp_fill_style_widget_fill_rule_activate ( GtkWidget *w, SPWidget *spw);
 
95
 
 
96
static void sp_fill_style_get_average_color_rgba    ( const GSList *objects, 
 
97
                                                      gfloat *c);
 
98
                                                      
 
99
static void sp_fill_style_get_average_color_cmyka   ( const GSList *objects, 
 
100
                                                      gfloat *c);
 
101
 
 
102
static SPPaintSelectorMode 
 
103
           sp_fill_style_determine_paint_selector_mode ( SPStyle *style );
 
104
 
 
105
static GtkWidget *dialog = NULL;
 
106
 
 
107
 
 
108
 
 
109
 
 
110
static void
 
111
sp_fill_style_dialog_destroy (GtkObject *object, gpointer data)
 
112
{
 
113
 
 
114
    dialog = NULL;
 
115
 
 
116
} // end of sp_fill_style_dialog_destroy()
 
117
 
 
118
 
 
119
 
 
120
void
 
121
sp_fill_style_dialog (void)
 
122
{
 
123
    if (!dialog)
 
124
    {
 
125
        
 
126
        GtkWidget *fs;
 
127
 
 
128
        dialog = sp_window_new (_("Fill style"), TRUE);
 
129
        g_signal_connect ( G_OBJECT (dialog), "destroy", 
 
130
                           G_CALLBACK (sp_fill_style_dialog_destroy), NULL );
 
131
 
 
132
        fs = sp_fill_style_widget_new ();
 
133
        gtk_widget_show (fs);
 
134
        gtk_container_add (GTK_CONTAINER (dialog), fs);
 
135
 
 
136
        gtk_widget_show (dialog);
 
137
        
 
138
    }
 
139
 
 
140
} // end of sp_fill_style_dialog()
 
141
 
 
142
 
 
143
 
 
144
 
 
145
GtkWidget *
 
146
sp_fill_style_widget_new (void)
 
147
{
 
148
    GtkWidget *spw, *vb, *psel, *hb, *l, *om, *m, *mi;
 
149
 
 
150
    spw = sp_widget_new_global (INKSCAPE);
 
151
 
 
152
    vb = gtk_vbox_new (FALSE, 0);
 
153
    gtk_widget_show (vb);
 
154
    gtk_container_add (GTK_CONTAINER (spw), vb);
 
155
 
 
156
    psel = sp_paint_selector_new ();
 
157
    gtk_widget_show (psel);
 
158
    gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0);
 
159
    g_object_set_data (G_OBJECT (spw), "paint-selector", psel);
 
160
 
 
161
    g_signal_connect ( G_OBJECT (psel), "mode_changed", 
 
162
                       G_CALLBACK (sp_fill_style_widget_paint_mode_changed), 
 
163
                       spw );
 
164
                      
 
165
    g_signal_connect ( G_OBJECT (psel), "dragged", 
 
166
                       G_CALLBACK (sp_fill_style_widget_paint_dragged), 
 
167
                       spw );
 
168
                      
 
169
    g_signal_connect ( G_OBJECT (psel), "changed", 
 
170
                       G_CALLBACK (sp_fill_style_widget_paint_changed), 
 
171
                       spw );
 
172
 
 
173
    hb = gtk_hbox_new (FALSE, 4);
 
174
    gtk_widget_show (hb);
 
175
    gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0);
 
176
 
 
177
    l = gtk_label_new (_("Fill Rule"));
 
178
    gtk_widget_show (l);
 
179
    gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
 
180
    gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0);
 
181
 
 
182
    om = gtk_option_menu_new ();
 
183
    gtk_widget_show (om);
 
184
    gtk_box_pack_start (GTK_BOX (hb), om, FALSE, FALSE, 0);
 
185
    g_object_set_data (G_OBJECT (spw), "fill-rule", om);
 
186
 
 
187
    /* 0 - nonzero 1 - evenodd */
 
188
    m = gtk_menu_new ();
 
189
    gtk_widget_show (m);
 
190
 
 
191
    mi = gtk_menu_item_new_with_label ("nonzero");
 
192
    gtk_widget_show (mi);
 
193
    gtk_menu_append (GTK_MENU (m), mi);
 
194
    g_object_set_data ( G_OBJECT (mi), "fill-rule", 
 
195
                        (void *)"nonzero" );
 
196
    g_signal_connect ( G_OBJECT (mi), "activate", 
 
197
                       G_CALLBACK (sp_fill_style_widget_fill_rule_activate), 
 
198
                       spw );
 
199
    mi = gtk_menu_item_new_with_label ("evenodd");
 
200
    gtk_widget_show (mi);
 
201
    gtk_menu_append (GTK_MENU (m), mi);
 
202
    g_object_set_data (G_OBJECT (mi), "fill-rule", (void *)"evenodd");
 
203
    g_signal_connect ( G_OBJECT (mi), "activate", 
 
204
                       G_CALLBACK (sp_fill_style_widget_fill_rule_activate), 
 
205
                       spw );
 
206
 
 
207
    gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m);
 
208
 
 
209
    g_signal_connect ( G_OBJECT (spw), "construct", 
 
210
                       G_CALLBACK (sp_fill_style_widget_construct), psel);
 
211
                       
 
212
    g_signal_connect ( G_OBJECT (spw), "modify_selection", 
 
213
                       G_CALLBACK (sp_fill_style_widget_modify_selection), psel);
 
214
                       
 
215
    g_signal_connect ( G_OBJECT (spw), "change_selection", 
 
216
                       G_CALLBACK (sp_fill_style_widget_change_selection), psel);
 
217
                       
 
218
    g_signal_connect ( G_OBJECT (spw), "attr_changed", 
 
219
                       G_CALLBACK (sp_fill_style_widget_attr_changed), psel);
 
220
 
 
221
    sp_fill_style_widget_update (SP_WIDGET (spw), 
 
222
        SP_ACTIVE_DESKTOP ? SP_DT_SELECTION (SP_ACTIVE_DESKTOP) : NULL);
 
223
 
 
224
    return spw;
 
225
    
 
226
} // end of sp_fill_style_widget_new()
 
227
 
 
228
 
 
229
 
 
230
void
 
231
sp_fill_style_widget_system_color_set ( GtkWidget *widget, 
 
232
                                        SPColor *color, 
 
233
                                        float opacity )
 
234
{
 
235
 
 
236
    SPPaintSelector *psel;
 
237
 
 
238
    psel = SP_PAINT_SELECTOR( g_object_get_data (G_OBJECT (widget), 
 
239
                              "paint-selector") );
 
240
 
 
241
    switch (psel->mode) {
 
242
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
 
243
        
 
244
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
245
            sp_paint_selector_system_color_set (psel, color, opacity);
 
246
            break;
 
247
        
 
248
        default:
 
249
            break;
 
250
    }
 
251
 
 
252
} // end of sp_fill_style_widget_system_color_set()
 
253
 
 
254
 
 
255
 
 
256
static void
 
257
sp_fill_style_widget_construct ( SPWidget *spw, SPPaintSelector *psel )
 
258
{
 
259
 
 
260
#ifdef SP_FS_VERBOSE
 
261
    g_print ( "Fill style widget constructed: inkscape %p repr %p\n", 
 
262
              spw->inkscape, spw->repr );
 
263
#endif
 
264
    if (spw->inkscape) {
 
265
    
 
266
        sp_fill_style_widget_update ( spw, 
 
267
            SP_ACTIVE_DESKTOP ? SP_DT_SELECTION (SP_ACTIVE_DESKTOP) : NULL );
 
268
    
 
269
    } else if (spw->repr) {
 
270
        
 
271
        sp_fill_style_widget_update_repr ( spw, spw->repr );
 
272
    
 
273
    }
 
274
    
 
275
} // end of sp_fill_style_widget_construct()
 
276
 
 
277
 
 
278
 
 
279
 
 
280
static void
 
281
sp_fill_style_widget_modify_selection ( SPWidget *spw, 
 
282
                                        SPSelection *selection, 
 
283
                                        guint flags, 
 
284
                                        SPPaintSelector *psel )
 
285
{
 
286
 
 
287
    if (flags & ( SP_OBJECT_MODIFIED_FLAG | 
 
288
                  SP_OBJECT_PARENT_MODIFIED_FLAG | 
 
289
                  SP_OBJECT_STYLE_MODIFIED_FLAG) )
 
290
    {
 
291
        sp_fill_style_widget_update (spw, selection);
 
292
    }
 
293
    
 
294
} // end of sp_fill_style_widget_modify_selection()
 
295
 
 
296
 
 
297
 
 
298
static void
 
299
sp_fill_style_widget_change_selection ( SPWidget *spw, 
 
300
                                        SPSelection *selection, 
 
301
                                        SPPaintSelector *psel )
 
302
{
 
303
 
 
304
    sp_fill_style_widget_update (spw, selection);
 
305
 
 
306
} // end of sp_fill_style_widget_change_selection()
 
307
 
 
308
 
 
309
 
 
310
static void
 
311
sp_fill_style_widget_attr_changed ( SPWidget *spw, const gchar *key, 
 
312
                                    const gchar *oldval, const gchar *newval )
 
313
{
 
314
 
 
315
    if (!strcmp (key, "style")) {
 
316
        /* This sounds interesting */
 
317
        sp_fill_style_widget_update_repr (spw, spw->repr);
 
318
    }
 
319
    
 
320
} // end of sp_fill_style_widget_attr_changed();
 
321
 
 
322
 
 
323
 
 
324
static void
 
325
sp_fill_style_widget_update ( SPWidget *spw, SPSelection *sel )
 
326
{
 
327
 
 
328
    SPPaintSelector *psel;
 
329
    GtkWidget *fillrule;
 
330
    SPPaintSelectorMode pselmode;
 
331
    const GSList *objects, *l;
 
332
    SPObject *object;
 
333
    SPGradient *vector;
 
334
    SPColor color;
 
335
    gfloat c[5];
 
336
    SPLinearGradient *lg;
 
337
    SPRadialGradient *rg;
 
338
    NRMatrix fctm, gs2d;
 
339
    NRRect fbb;
 
340
 
 
341
    
 
342
    if (g_object_get_data (G_OBJECT (spw), "update"))
 
343
        return;
 
344
 
 
345
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
346
 
 
347
    psel = SP_PAINT_SELECTOR (g_object_get_data ( G_OBJECT (spw), 
 
348
                                                  "paint-selector"));
 
349
 
 
350
    if (!sel || sp_selection_is_empty (sel)) {
 
351
        /* No objects, set empty */
 
352
        sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
 
353
        g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
354
        return;
 
355
    }
 
356
 
 
357
    objects = sp_selection_item_list (sel);
 
358
    object = SP_OBJECT (objects->data);
 
359
    pselmode = 
 
360
        (SPPaintSelectorMode)sp_fill_style_determine_paint_selector_mode 
 
361
            (SP_OBJECT_STYLE (object));
 
362
 
 
363
    for (l = objects->next; l != NULL; l = l->next) {
 
364
        SPPaintSelectorMode nextmode;
 
365
        nextmode = 
 
366
            sp_fill_style_determine_paint_selector_mode 
 
367
                (SP_OBJECT_STYLE (l->data));
 
368
                
 
369
        if (nextmode != pselmode) {
 
370
            /* Multiple styles */
 
371
            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
 
372
            g_object_set_data ( G_OBJECT (spw), "update", 
 
373
                                GINT_TO_POINTER (FALSE));
 
374
            return;
 
375
        }
 
376
    }
 
377
    
 
378
#ifdef SP_FS_VERBOSE
 
379
    g_print ("FillStyleWidget: paint selector mode %d\n", pselmode);
 
380
#endif
 
381
    
 
382
    switch (pselmode) {
 
383
 
 
384
        case SP_PAINT_SELECTOR_MODE_NONE:
 
385
            /* No paint at all */
 
386
            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_NONE);
 
387
            break;
 
388
            
 
389
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
 
390
            sp_paint_selector_set_mode ( psel, 
 
391
                                         SP_PAINT_SELECTOR_MODE_COLOR_RGB);
 
392
            sp_fill_style_get_average_color_rgba (objects, c);
 
393
            sp_color_set_rgb_float (&color, c[0], c[1], c[2]);
 
394
            sp_paint_selector_set_color_alpha (psel, &color, c[3]);
 
395
            break;
 
396
        
 
397
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
398
            sp_paint_selector_set_mode ( psel, 
 
399
                                         SP_PAINT_SELECTOR_MODE_COLOR_CMYK);
 
400
            sp_fill_style_get_average_color_cmyka (objects, c);
 
401
            sp_color_set_cmyk_float (&color, c[0], c[1], c[2], c[3]);
 
402
            sp_paint_selector_set_color_alpha (psel, &color, c[4]);
 
403
            break;
 
404
        
 
405
        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
 
406
            object = SP_OBJECT (objects->data);
 
407
            /* We know that all objects have lineargradient fill style */
 
408
            vector = 
 
409
                sp_gradient_get_vector ( SP_GRADIENT 
 
410
                                            (SP_OBJECT_STYLE_FILL_SERVER 
 
411
                                                (object)), 
 
412
                                         FALSE );
 
413
            
 
414
            for (l = objects->next; l != NULL; l = l->next) {
 
415
                SPObject *next;
 
416
                next = SP_OBJECT (l->data);
 
417
                
 
418
                if (sp_gradient_get_vector ( SP_GRADIENT 
 
419
                                             (SP_OBJECT_STYLE_FILL_SERVER 
 
420
                                                 (next)), 
 
421
                                             FALSE) != vector )
 
422
                {
 
423
                    /* Multiple vectors */
 
424
                    sp_paint_selector_set_mode ( psel, 
 
425
                            SP_PAINT_SELECTOR_MODE_MULTIPLE);
 
426
                            
 
427
                    g_object_set_data ( G_OBJECT (spw), "update", 
 
428
                                        GINT_TO_POINTER (FALSE));
 
429
                    return;
 
430
                    
 
431
                } // end of if
 
432
                
 
433
            } // end of for()
 
434
            
 
435
            /* TODO: Probably we should set multiple mode here too */
 
436
            sp_paint_selector_set_gradient_linear (psel, vector);
 
437
            sp_selection_bbox_document (sel, &fbb);
 
438
            sp_paint_selector_set_gradient_bbox ( psel, fbb.x0, fbb.y0, 
 
439
                                                  fbb.x1, fbb.y1 );
 
440
 
 
441
            /* TODO: This is plain wrong */
 
442
            lg = SP_LINEARGRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object));
 
443
            sp_item_invoke_bbox (SP_ITEM (object), &fbb, NULL, TRUE);
 
444
            sp_item_i2doc_affine (SP_ITEM (object), &fctm);
 
445
            sp_gradient_get_gs2d_matrix_f ( SP_GRADIENT (lg), &fctm, &fbb, 
 
446
                                            &gs2d);
 
447
            sp_paint_selector_set_gradient_gs2d_matrix_f (psel, &gs2d);
 
448
            sp_paint_selector_set_gradient_properties (psel, 
 
449
                                                       SP_GRADIENT_UNITS (lg), 
 
450
                                                       SP_GRADIENT_SPREAD (lg));
 
451
                                                       
 
452
            sp_paint_selector_set_lgradient_position ( psel, lg->x1.computed, 
 
453
                                                       lg->y1.computed, 
 
454
                                                       lg->x2.computed, 
 
455
                                                       lg->y2.computed );
 
456
            break;
 
457
            
 
458
        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
 
459
            object = SP_OBJECT (objects->data);
 
460
            
 
461
            /* We know that all objects have radialgradient fill style */
 
462
            vector = 
 
463
                sp_gradient_get_vector ( SP_GRADIENT 
 
464
                                            (SP_OBJECT_STYLE_FILL_SERVER 
 
465
                                                (object)), 
 
466
                                         FALSE );
 
467
                                         
 
468
            for (l = objects->next; l != NULL; l = l->next) {
 
469
                SPObject *next;
 
470
                next = SP_OBJECT (l->data);
 
471
                if (sp_gradient_get_vector ( SP_GRADIENT 
 
472
                                                (SP_OBJECT_STYLE_FILL_SERVER 
 
473
                                                    (next)), 
 
474
                                             FALSE) != vector )
 
475
                {
 
476
                    /* Multiple vectors */
 
477
                    sp_paint_selector_set_mode ( psel, 
 
478
                            SP_PAINT_SELECTOR_MODE_MULTIPLE);
 
479
                    g_object_set_data ( G_OBJECT (spw), 
 
480
                                        "update", GINT_TO_POINTER (FALSE) );
 
481
                    return;
 
482
                }
 
483
                
 
484
            } // end of for loop
 
485
            
 
486
            /* TODO: Probably we should set multiple mode here too */
 
487
            sp_paint_selector_set_gradient_radial (psel, vector);
 
488
            sp_selection_bbox_document (sel, &fbb);
 
489
            sp_paint_selector_set_gradient_bbox ( psel, fbb.x0, fbb.y0, 
 
490
                                                  fbb.x1, fbb.y1);
 
491
            
 
492
            /* TODO: This is plain wrong */
 
493
            rg = SP_RADIALGRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object));
 
494
            sp_item_invoke_bbox (SP_ITEM (object), &fbb, NULL, TRUE);
 
495
            sp_item_i2doc_affine (SP_ITEM (object), &fctm);
 
496
            sp_gradient_get_gs2d_matrix_f ( SP_GRADIENT (rg), &fctm, 
 
497
                                            &fbb, &gs2d);
 
498
            sp_paint_selector_set_gradient_gs2d_matrix_f (psel, &gs2d);
 
499
            sp_paint_selector_set_gradient_properties (psel, 
 
500
                                                       SP_GRADIENT_UNITS (rg), 
 
501
                                                       SP_GRADIENT_SPREAD (rg));
 
502
                                                       
 
503
            sp_paint_selector_set_rgradient_position ( psel, 
 
504
                                                        rg->cx.computed, 
 
505
                                                       rg->cy.computed, 
 
506
                                                       rg->fx.computed, 
 
507
                                                       rg->fy.computed, 
 
508
                                                       rg->r.computed );
 
509
            
 
510
            break;
 
511
            
 
512
        default:
 
513
            sp_paint_selector_set_mode ( psel, 
 
514
                                         SP_PAINT_SELECTOR_MODE_MULTIPLE );
 
515
            break;
 
516
    
 
517
    } // end of switch
 
518
 
 
519
    fillrule = GTK_WIDGET(g_object_get_data (G_OBJECT (spw), "fill-rule"));
 
520
    gtk_option_menu_set_history ( GTK_OPTION_MENU (fillrule), 
 
521
            (SP_OBJECT_STYLE 
 
522
                (object)->fill_rule.computed == ART_WIND_RULE_NONZERO) ? 0 : 1);
 
523
 
 
524
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
525
 
 
526
} // end of sp_fill_style_widget_update()
 
527
 
 
528
 
 
529
 
 
530
static void
 
531
sp_fill_style_widget_update_repr (SPWidget *spw, SPRepr *repr)
 
532
{
 
533
 
 
534
    SPPaintSelector *psel;
 
535
    GtkWidget *fillrule;
 
536
    SPPaintSelectorMode pselmode;
 
537
    SPStyle *style;
 
538
    SPColor color;
 
539
    gfloat c[5];
 
540
 
 
541
    if (g_object_get_data (G_OBJECT (spw), "update"))
 
542
        return;
 
543
 
 
544
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
545
 
 
546
#ifdef SP_FS_VERBOSE
 
547
    g_print ("FillStyleWidget: Set update flag\n");
 
548
#endif
 
549
    psel = SP_PAINT_SELECTOR(g_object_get_data ( G_OBJECT (spw), 
 
550
                                                 "paint-selector") );
 
551
 
 
552
    style = sp_style_new ();
 
553
    sp_style_read_from_repr (style, repr);
 
554
 
 
555
    pselmode = sp_fill_style_determine_paint_selector_mode (style);
 
556
    
 
557
#ifdef SP_FS_VERBOSE
 
558
    g_print ("FillStyleWidget: paint selector mode %d\n", pselmode);
 
559
#endif
 
560
 
 
561
    switch (pselmode) {
 
562
        case SP_PAINT_SELECTOR_MODE_NONE:
 
563
            /* No paint at all */
 
564
            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_NONE);
 
565
            break;
 
566
            
 
567
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
 
568
            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_COLOR_RGB);
 
569
            sp_color_get_rgb_floatv (&style->fill.value.color, c);
 
570
            c[3] = SP_SCALE24_TO_FLOAT (style->fill_opacity.value);
 
571
            sp_color_set_rgb_float (&color, c[0], c[1], c[2]);
 
572
            sp_paint_selector_set_color_alpha (psel, &color, c[3]);
 
573
            break;
 
574
            
 
575
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
576
            sp_paint_selector_set_mode ( psel, 
 
577
                                         SP_PAINT_SELECTOR_MODE_COLOR_CMYK);
 
578
            sp_color_get_cmyk_floatv (&style->fill.value.color, c);
 
579
            c[4] = SP_SCALE24_TO_FLOAT (style->fill_opacity.value);
 
580
            sp_color_set_cmyk_float (&color, c[0], c[1], c[2], c[3]);
 
581
            sp_paint_selector_set_color_alpha (psel, &color, c[4]);
 
582
            break;
 
583
            
 
584
        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
 
585
            break;
 
586
            
 
587
        default:
 
588
            break;
 
589
    }
 
590
 
 
591
    fillrule = GTK_WIDGET(g_object_get_data (G_OBJECT (spw), "fill-rule"));
 
592
    gtk_option_menu_set_history ( GTK_OPTION_MENU (fillrule), 
 
593
            (style->fill_rule.computed == ART_WIND_RULE_NONZERO) ? 0 : 1);
 
594
 
 
595
    sp_style_unref (style);
 
596
 
 
597
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
598
    
 
599
#ifdef SP_FS_VERBOSE
 
600
    g_print ("FillStyleWidget: Cleared update flag\n");
 
601
#endif
 
602
 
 
603
} // end of sp_fill_style_widget_update_repr()
 
604
 
 
605
 
 
606
 
 
607
static void
 
608
sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel, 
 
609
                                          SPPaintSelectorMode mode, 
 
610
                                          SPWidget *spw )
 
611
{
 
612
 
 
613
    if (g_object_get_data (G_OBJECT (spw), "update"))
 
614
        return;
 
615
 
 
616
    /* TODO: Does this work? */
 
617
    /* TODO: Not really, here we have to get old color back from object */
 
618
    /* Instead of relying on paint widget having meaningful colors set */
 
619
    sp_fill_style_widget_paint_changed (psel, spw);
 
620
 
 
621
} // end of sp_fill_style_widget_paint_mode_changed()
 
622
 
 
623
 
 
624
 
 
625
static void
 
626
sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
 
627
{
 
628
    const GSList *items, *i;
 
629
    SPGradient *vector;
 
630
    SPColor color;
 
631
    gfloat alpha;
 
632
 
 
633
    if (!spw->inkscape) return;
 
634
    if (g_object_get_data (G_OBJECT (spw), "update")) return;
 
635
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
636
#ifdef SP_FS_VERBOSE
 
637
    g_print ("FillStyleWidget: paint dragged\n");
 
638
#endif
 
639
    switch (psel->mode) {
 
640
        case SP_PAINT_SELECTOR_MODE_EMPTY:
 
641
        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
 
642
        case SP_PAINT_SELECTOR_MODE_NONE:
 
643
            g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'",
 
644
                        __FILE__, __LINE__, psel->mode );
 
645
            break;
 
646
            
 
647
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
 
648
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
649
            sp_paint_selector_get_color_alpha (psel, &color, &alpha);
 
650
            items = sp_widget_get_item_list (spw);
 
651
            for (i = items; i != NULL; i = i->next) {
 
652
                sp_style_set_fill_color_alpha ( SP_OBJECT_STYLE (i->data), 
 
653
                                                &color, alpha, TRUE, TRUE);
 
654
            }
 
655
            break;
 
656
            
 
657
        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
 
658
            vector = sp_paint_selector_get_gradient_vector (psel);
 
659
            vector = sp_gradient_ensure_vector_normalized (vector);
 
660
            items = sp_widget_get_item_list (spw);
 
661
            for (i = items; i != NULL; i = i->next) {
 
662
                SPGradient *lg;
 
663
                lg = sp_item_force_fill_lineargradient_vector ( SP_ITEM 
 
664
                                                                    (i->data), 
 
665
                                                                vector );
 
666
                sp_paint_selector_write_lineargradient ( psel, 
 
667
                                                         SP_LINEARGRADIENT (lg),
 
668
                                                         SP_ITEM (i->data) );
 
669
            }
 
670
            break;
 
671
            
 
672
        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
 
673
            vector = sp_paint_selector_get_gradient_vector (psel);
 
674
            vector = sp_gradient_ensure_vector_normalized (vector);
 
675
            items = sp_widget_get_item_list (spw);
 
676
            
 
677
            for (i = items; i != NULL; i = i->next) {
 
678
                SPGradient *rg;
 
679
                rg = sp_item_force_fill_radialgradient_vector ( SP_ITEM 
 
680
                                                                    (i->data),
 
681
                                                                vector );
 
682
                sp_paint_selector_write_radialgradient ( psel, 
 
683
                                                         SP_RADIALGRADIENT (rg),
 
684
                                                         SP_ITEM (i->data) );
 
685
            }
 
686
            break;
 
687
            
 
688
        default:
 
689
            g_warning ( "file %s: line %d: Paint selector should not be in " 
 
690
                        "mode %d", 
 
691
                        __FILE__, __LINE__, psel->mode);
 
692
            break;
 
693
            
 
694
    } // end of switch
 
695
    
 
696
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
697
    
 
698
} // end of sp_fill_style_widget_paint_dragged()
 
699
 
 
700
 
 
701
 
 
702
static void
 
703
sp_fill_style_widget_paint_changed ( SPPaintSelector *psel, 
 
704
                                     SPWidget *spw )
 
705
{
 
706
 
 
707
    const GSList *items, *i, *r;
 
708
    GSList *reprs;
 
709
    SPCSSAttr *css;
 
710
    SPColor color;
 
711
    gfloat alpha;
 
712
    guint32 rgba;
 
713
    gfloat cmyk[4];
 
714
    SPGradient *vector;
 
715
    gchar b[64];
 
716
        Inkscape::SVGOStringStream osalpha, oscolour;
 
717
 
 
718
    
 
719
    if (g_object_get_data (G_OBJECT (spw), "update")) return;
 
720
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
721
 
 
722
#ifdef SP_FS_VERBOSE
 
723
    g_print ("FillStyleWidget: paint changed\n");
 
724
#endif
 
725
    
 
726
    if (spw->inkscape) {
 
727
        /* fixme: */
 
728
        if (!SP_WIDGET_DOCUMENT (spw)) {
 
729
            g_object_set_data ( G_OBJECT (spw), "update", 
 
730
                                GINT_TO_POINTER (FALSE) );
 
731
            return;
 
732
        }
 
733
        reprs = NULL;
 
734
        items = sp_widget_get_item_list (spw);
 
735
        for (i = items; i != NULL; i = i->next) {
 
736
            reprs = g_slist_prepend (reprs, SP_OBJECT_REPR (i->data));
 
737
        }
 
738
    } else {
 
739
        reprs = g_slist_prepend (NULL, spw->repr);
 
740
        items = NULL;
 
741
    }
 
742
 
 
743
    switch (psel->mode) {
 
744
    
 
745
        case SP_PAINT_SELECTOR_MODE_EMPTY:
 
746
        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
 
747
            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'", 
 
748
                        __FILE__, __LINE__, psel->mode);
 
749
            break;
 
750
            
 
751
        case SP_PAINT_SELECTOR_MODE_NONE:
 
752
            css = sp_repr_css_attr_new ();
 
753
            sp_repr_css_set_property (css, "fill", "none");
 
754
            for (r = reprs; r != NULL; r = r->next) {
 
755
                sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
 
756
                sp_repr_set_attr_recursive ( (SPRepr *) r->data, 
 
757
                                            "sodipodi:fill-cmyk", NULL);
 
758
            }
 
759
            sp_repr_css_attr_unref (css);
 
760
            if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw));
 
761
            break;
 
762
 
 
763
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
 
764
            css = sp_repr_css_attr_new ();
 
765
            sp_paint_selector_get_color_alpha (psel, &color, &alpha);
 
766
            rgba = sp_color_get_rgba32_falpha (&color, alpha);
 
767
            sp_svg_write_color (b, 64, rgba);
 
768
            sp_repr_css_set_property (css, "fill", b);
 
769
            osalpha << alpha;
 
770
            sp_repr_css_set_property (css, "fill-opacity", osalpha.str().c_str());
 
771
            for (r = reprs; r != NULL; r = r->next) {
 
772
                sp_repr_set_attr_recursive ( (SPRepr *) r->data, 
 
773
                                             "sodipodi:fill-cmyk", NULL);
 
774
                sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
 
775
            }
 
776
            sp_repr_css_attr_unref (css);
 
777
            if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw));
 
778
            break;
 
779
            
 
780
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
781
            css = sp_repr_css_attr_new ();
 
782
            sp_paint_selector_get_color_alpha (psel, &color, &alpha);
 
783
            rgba = sp_color_get_rgba32_falpha (&color, alpha);
 
784
            sp_svg_write_color (b, 64, rgba);
 
785
            sp_repr_css_set_property (css, "fill", b);
 
786
            osalpha << alpha;
 
787
            sp_repr_css_set_property (css, "fill-opacity", osalpha.str().c_str());
 
788
            sp_color_get_cmyk_floatv (&color, cmyk);
 
789
            oscolour << "(" << cmyk[0] << " " << cmyk[1] << " " << cmyk[2] << " " << cmyk[3] << ")";
 
790
                         
 
791
            for (r = reprs; r != NULL; r = r->next) {
 
792
                sp_repr_set_attr_recursive ( (SPRepr *) r->data, 
 
793
                                             "sodipodi:fill-cmyk", oscolour.str().c_str() );
 
794
                sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
 
795
            }
 
796
            sp_repr_css_attr_unref (css);
 
797
            if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw));
 
798
            break;
 
799
            
 
800
        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
 
801
            
 
802
            if (items) {
 
803
                vector = sp_paint_selector_get_gradient_vector (psel);
 
804
                
 
805
                if (!vector) {
 
806
                    /* No vector in paint selector should mean that we just 
 
807
                     * changed mode 
 
808
                     */
 
809
                    vector = sp_document_default_gradient_vector 
 
810
                                 (SP_WIDGET_DOCUMENT (spw));
 
811
                                 
 
812
                    for (i = items; i != NULL; i = i->next) {
 
813
                        sp_item_force_fill_lineargradient_vector 
 
814
                            (SP_ITEM (i->data), vector );
 
815
                    }
 
816
                } else {
 
817
                
 
818
                    vector = sp_gradient_ensure_vector_normalized (vector);
 
819
                    for (i = items; i != NULL; i = i->next) {
 
820
                        SPGradient *lg;
 
821
                        lg = sp_item_force_fill_lineargradient_vector 
 
822
                                 (SP_ITEM (i->data), vector );
 
823
                        sp_paint_selector_write_lineargradient ( psel, 
 
824
                                SP_LINEARGRADIENT (lg), SP_ITEM (i->data));
 
825
                        sp_object_invoke_write ( SP_OBJECT (lg), 
 
826
                                                 SP_OBJECT_REPR (lg), 
 
827
                                                 SP_OBJECT_WRITE_EXT );
 
828
                    }
 
829
                }
 
830
                sp_document_done (SP_WIDGET_DOCUMENT (spw));
 
831
            }
 
832
            break;
 
833
            
 
834
        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
 
835
        
 
836
            if (items) {
 
837
                
 
838
                vector = sp_paint_selector_get_gradient_vector (psel);
 
839
                if (!vector) {
 
840
                
 
841
                    /* No vector in paint selector should mean that we just 
 
842
                     * changed mode 
 
843
                     */
 
844
                    vector = sp_document_default_gradient_vector 
 
845
                                 (SP_WIDGET_DOCUMENT (spw));
 
846
                                 
 
847
                    for (i = items; i != NULL; i = i->next) {
 
848
                        sp_item_force_fill_radialgradient_vector 
 
849
                            (SP_ITEM (i->data), vector );
 
850
                    }
 
851
                    
 
852
                } else {
 
853
                    vector = sp_gradient_ensure_vector_normalized (vector);
 
854
                    for (i = items; i != NULL; i = i->next) {
 
855
                        SPGradient *rg;
 
856
                        rg = sp_item_force_fill_radialgradient_vector 
 
857
                                 (SP_ITEM (i->data), vector);
 
858
                        sp_paint_selector_write_radialgradient (psel, 
 
859
                                SP_RADIALGRADIENT (rg), SP_ITEM (i->data));
 
860
                        sp_object_invoke_write ( SP_OBJECT (rg), 
 
861
                                                 SP_OBJECT_REPR (rg), 
 
862
                                                 SP_OBJECT_WRITE_EXT );
 
863
                    }
 
864
                } // end if
 
865
                
 
866
                sp_document_done (SP_WIDGET_DOCUMENT (spw));
 
867
            } // end if
 
868
            
 
869
            break;
 
870
            
 
871
        default:
 
872
            g_warning ( "file %s: line %d: Paint selector should not be in " 
 
873
                        "mode %d", 
 
874
                        __FILE__, __LINE__, psel->mode );
 
875
            break;
 
876
    }
 
877
 
 
878
    g_slist_free (reprs);
 
879
 
 
880
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
881
 
 
882
    
 
883
} // end of sp_fill_style_widget_paint_changed()
 
884
 
 
885
 
 
886
 
 
887
static void
 
888
sp_fill_style_widget_fill_rule_activate (GtkWidget *w, SPWidget *spw)
 
889
{
 
890
 
 
891
    const GSList *items, *i, *r;
 
892
    GSList *reprs;
 
893
    SPCSSAttr *css;
 
894
 
 
895
    if (g_object_get_data (G_OBJECT (spw), "update"))
 
896
        return;
 
897
 
 
898
    if (spw->inkscape) {
 
899
        reprs = NULL;
 
900
        items = sp_widget_get_item_list (spw);
 
901
        
 
902
        for (i = items; i != NULL; i = i->next) {
 
903
            reprs = g_slist_prepend (reprs, SP_OBJECT_REPR (i->data));
 
904
        }
 
905
        
 
906
    } else {
 
907
    
 
908
        reprs = g_slist_prepend (NULL, spw->repr);
 
909
        items = NULL;
 
910
    }
 
911
 
 
912
    css = sp_repr_css_attr_new ();
 
913
    sp_repr_css_set_property ( css, "fill-rule", 
 
914
                               (const gchar *)g_object_get_data (G_OBJECT (w), 
 
915
                               "fill-rule") );
 
916
                               
 
917
    for (r = reprs; r != NULL; r = r->next) {
 
918
        sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
 
919
    }
 
920
    
 
921
    sp_repr_css_attr_unref (css);
 
922
    
 
923
    if (spw->inkscape) 
 
924
        sp_document_done (SP_WIDGET_DOCUMENT (spw));
 
925
 
 
926
    g_slist_free (reprs);
 
927
    
 
928
} // end of sp_fill_style_widget_fill_rule_activate()
 
929
 
 
930
 
 
931
 
 
932
 
 
933
static void
 
934
sp_fill_style_get_average_color_rgba (const GSList *objects, gfloat *c)
 
935
{
 
936
    gint num;
 
937
 
 
938
    c[0] = 0.0;
 
939
    c[1] = 0.0;
 
940
    c[2] = 0.0;
 
941
    c[3] = 0.0;
 
942
    num = 0;
 
943
 
 
944
    while (objects) {
 
945
        SPObject *object;
 
946
        gfloat d[3];
 
947
        object = SP_OBJECT (objects->data);
 
948
        if (object->style->fill.type == SP_PAINT_TYPE_COLOR) {
 
949
            sp_color_get_rgb_floatv (&object->style->fill.value.color, d);
 
950
            c[0] += d[0];
 
951
            c[1] += d[1];
 
952
            c[2] += d[2];
 
953
            c[3] += SP_SCALE24_TO_FLOAT (object->style->fill_opacity.value);
 
954
        }
 
955
        num += 1;
 
956
        objects = objects->next;
 
957
    }
 
958
 
 
959
    c[0] /= num;
 
960
    c[1] /= num;
 
961
    c[2] /= num;
 
962
    c[3] /= num;
 
963
    
 
964
} // end of sp_fill_style_get_average_color_rgba()
 
965
 
 
966
 
 
967
 
 
968
static void
 
969
sp_fill_style_get_average_color_cmyka (const GSList *objects, gfloat *c)
 
970
{
 
971
    gint num;
 
972
 
 
973
    c[0] = 0.0;
 
974
    c[1] = 0.0;
 
975
    c[2] = 0.0;
 
976
    c[3] = 0.0;
 
977
    c[4] = 0.0;
 
978
    num = 0;
 
979
 
 
980
    while (objects) {
 
981
        SPObject *object;
 
982
        gfloat d[4];
 
983
        object = SP_OBJECT (objects->data);
 
984
        if (object->style->fill.type == SP_PAINT_TYPE_COLOR) {
 
985
            sp_color_get_cmyk_floatv (&object->style->fill.value.color, d);
 
986
            c[0] += d[0];
 
987
            c[1] += d[1];
 
988
            c[2] += d[2];
 
989
            c[3] += d[3];
 
990
            c[4] += SP_SCALE24_TO_FLOAT (object->style->fill_opacity.value);
 
991
        }
 
992
        num += 1;
 
993
        objects = objects->next;
 
994
    }
 
995
 
 
996
    c[0] /= num;
 
997
    c[1] /= num;
 
998
    c[2] /= num;
 
999
    c[3] /= num;
 
1000
    c[4] /= num;
 
1001
 
 
1002
} // end of sp_fill_style_get_average_color_cmyka()
 
1003
 
 
1004
 
 
1005
 
 
1006
 
 
1007
static SPPaintSelectorMode
 
1008
sp_fill_style_determine_paint_selector_mode (SPStyle *style)
 
1009
{
 
1010
    SPColorSpaceType cstype;
 
1011
 
 
1012
    switch (style->fill.type) {
 
1013
    
 
1014
        case SP_PAINT_TYPE_NONE:
 
1015
            return SP_PAINT_SELECTOR_MODE_NONE;
 
1016
            
 
1017
        case SP_PAINT_TYPE_COLOR:
 
1018
            cstype = sp_color_get_colorspace_type (&style->fill.value.color);
 
1019
            
 
1020
            switch (cstype) {
 
1021
                case SP_COLORSPACE_TYPE_RGB:
 
1022
                    return SP_PAINT_SELECTOR_MODE_COLOR_RGB;
 
1023
                case SP_COLORSPACE_TYPE_CMYK:
 
1024
                    return SP_PAINT_SELECTOR_MODE_COLOR_CMYK;
 
1025
                default:
 
1026
                    g_warning ( "file %s: line %d: Unknown colorspace type %d",
 
1027
                                __FILE__, __LINE__, cstype );
 
1028
                    return SP_PAINT_SELECTOR_MODE_NONE;
 
1029
            }
 
1030
            
 
1031
        case SP_PAINT_TYPE_PAINTSERVER:
 
1032
        
 
1033
            if (SP_IS_LINEARGRADIENT (SP_STYLE_FILL_SERVER (style))) {
 
1034
                
 
1035
                return SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR;
 
1036
            
 
1037
            } else if (SP_IS_RADIALGRADIENT (SP_STYLE_FILL_SERVER (style))) {
 
1038
                
 
1039
                return SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL;
 
1040
            }
 
1041
            
 
1042
            g_warning ( "file %s: line %d: Unknown paintserver", 
 
1043
                        __FILE__, __LINE__ );
 
1044
            return SP_PAINT_SELECTOR_MODE_NONE;
 
1045
            
 
1046
            
 
1047
        default:
 
1048
            g_warning ( "file %s: line %d: Unknown paint type %d", 
 
1049
                        __FILE__, __LINE__, style->fill.type );
 
1050
            break;
 
1051
    }
 
1052
 
 
1053
    return SP_PAINT_SELECTOR_MODE_NONE;
 
1054
 
 
1055
} // end of sp_fill_style_determine_paint_selector_mode()
 
1056
 
 
1057
 
 
1058
 
 
1059
/*
 
1060
  Local Variables:
 
1061
  mode:c++
 
1062
  c-file-style:"stroustrup"
 
1063
  c-file-offsets:((innamespace . 0)(inline-open . 0))
 
1064
  indent-tabs-mode:nil
 
1065
  fill-column:99
 
1066
  End:
 
1067
*/
 
1068
// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :