~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/dropper-context.cpp

  • Committer: JazzyNico
  • Date: 2011-08-29 20:25:30 UTC
  • Revision ID: nicoduf@yahoo.fr-20110829202530-6deuoz11q90usldv
Code refactoring and merging with trunk (revision 10599).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define __SP_DROPPER_CONTEXT_C__
2
 
 
3
1
/*
4
2
 * Tool for picking colors from drawing
5
3
 *
6
4
 * Authors:
7
5
 *   Lauris Kaplinski <lauris@kaplinski.com>
8
6
 *   bulia byak <buliabyak@users.sf.net>
 
7
 *   Abhishek Sharma
9
8
 *
10
9
 * Copyright (C) 1999-2005 Authors
11
10
 *
16
15
# include <config.h>
17
16
#endif
18
17
 
19
 
#include <glibmm/i18n.h>
20
 
#include <glibmm/ustring.h>
21
 
#include <glibmm/refptr.h>
22
 
#include <gtkmm/clipboard.h>
23
 
#include <gdk/gdkkeysyms.h>
 
18
#include <glibmm.h>
 
19
#include <gtkmm.h>
 
20
#include <gdk/gdk.h>
 
21
#include <2geom/transforms.h>
24
22
 
25
23
#include "macros.h"
26
24
#include "display/canvas-bpath.h"
27
25
#include "display/canvas-arena.h"
28
26
#include "display/curve.h"
 
27
#include "display/cairo-utils.h"
29
28
#include "svg/svg-color.h"
30
29
#include "color.h"
31
30
#include "color-rgba.h"
41
40
 
42
41
#include "dropper-context.h"
43
42
#include "message-context.h"
44
 
//#include "libnr/nr-scale-translate-ops.h"
 
43
 
 
44
using Inkscape::DocumentUndo;
45
45
 
46
46
static void sp_dropper_context_class_init(SPDropperContextClass *klass);
47
47
static void sp_dropper_context_init(SPDropperContext *dc);
202
202
                // otherwise, constantly calculate color no matter is any button pressed or not
203
203
 
204
204
                double rw = 0.0;
205
 
                double W(0), R(0), G(0), B(0), A(0);
 
205
                double R(0), G(0), B(0), A(0);
206
206
 
207
207
                if (dc->dragging) {
208
208
                    // calculate average
215
215
                    }
216
216
 
217
217
                    Geom::Point const cd = desktop->w2d(dc->centre);
218
 
                    Geom::Matrix const w2dt = desktop->w2d();
 
218
                    Geom::Affine const w2dt = desktop->w2d();
219
219
                    const double scale = rw * w2dt.descrim();
220
 
                    Geom::Matrix const sm( Geom::Scale(scale, scale) * Geom::Translate(cd) );
 
220
                    Geom::Affine const sm( Geom::Scale(scale, scale) * Geom::Translate(cd) );
221
221
                    sp_canvas_item_affine_absolute(dc->area, sm);
222
222
                    sp_canvas_item_show(dc->area);
223
223
 
224
224
                    /* Get buffer */
225
 
                    const int x0 = (int) floor(dc->centre[Geom::X] - rw);
226
 
                    const int y0 = (int) floor(dc->centre[Geom::Y] - rw);
227
 
                    const int x1 = (int) ceil(dc->centre[Geom::X] + rw);
228
 
                    const int y1 = (int) ceil(dc->centre[Geom::Y] + rw);
229
 
 
230
 
                    if ((x1 > x0) && (y1 > y0)) {
231
 
                        NRPixBlock pb;
232
 
                        nr_pixblock_setup_fast(&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, x0, y0, x1, y1, TRUE);
233
 
                        /* fixme: (Lauris) */
234
 
                        sp_canvas_arena_render_pixblock(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), &pb);
235
 
                        for (int y = y0; y < y1; y++) {
236
 
                            const unsigned char *s = NR_PIXBLOCK_PX(&pb) + (y - y0) * pb.rs;
237
 
                            for (int x = x0; x < x1; x++) {
238
 
                                const double dx = x - dc->centre[Geom::X];
239
 
                                const double dy = y - dc->centre[Geom::Y];
240
 
                                const double w = exp(-((dx * dx) + (dy * dy)) / (rw * rw));
241
 
                                W += w;
242
 
                                R += w * s[0];
243
 
                                G += w * s[1];
244
 
                                B += w * s[2];
245
 
                                A += w * s[3];
246
 
                                s += 4;
247
 
                            }
248
 
                        }
249
 
                        nr_pixblock_release(&pb);
250
 
 
251
 
                        R = (R + 0.001) / (255.0 * W);
252
 
                        G = (G + 0.001) / (255.0 * W);
253
 
                        B = (B + 0.001) / (255.0 * W);
254
 
                        A = (A + 0.001) / (255.0 * W);
255
 
 
256
 
                        R = CLAMP(R, 0.0, 1.0);
257
 
                        G = CLAMP(G, 0.0, 1.0);
258
 
                        B = CLAMP(B, 0.0, 1.0);
259
 
                        A = CLAMP(A, 0.0, 1.0);
 
225
                    Geom::Rect r(dc->centre, dc->centre);
 
226
                    r.expandBy(rw);
 
227
                    if (!r.hasZeroArea()) {
 
228
                        Geom::IntRect area = r.roundOutwards();
 
229
                        cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, area.width(), area.height());
 
230
                        sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area);
 
231
                        ink_cairo_surface_average_color_premul(s, R, G, B, A);
 
232
                        cairo_surface_destroy(s);
260
233
                    }
261
 
 
262
234
                } else {
263
235
                    // pick single pixel
264
 
                    NRPixBlock pb;
265
 
                    int x = (int) floor(event->button.x);
266
 
                    int y = (int) floor(event->button.y);
267
 
                    nr_pixblock_setup_fast(&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, x, y, x+1, y+1, TRUE);
268
 
                    sp_canvas_arena_render_pixblock(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), &pb);
269
 
                    const unsigned char *s = NR_PIXBLOCK_PX(&pb);
270
 
 
271
 
                    R = s[0] / 255.0;
272
 
                    G = s[1] / 255.0;
273
 
                    B = s[2] / 255.0;
274
 
                    A = s[3] / 255.0;
 
236
                    Geom::IntRect area = Geom::IntRect::from_xywh(floor(event->button.x), floor(event->button.y), 1, 1);
 
237
                    cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
 
238
                    sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area);
 
239
                    ink_cairo_surface_average_color_premul(s, R, G, B, A);
 
240
                    cairo_surface_destroy(s);
275
241
                }
276
242
 
277
243
                if (pick == SP_DROPPER_PICK_VISIBLE) {
350
316
 
351
317
 
352
318
                if (!(sp_desktop_selection(desktop)->isEmpty())) {
353
 
                    sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_DROPPER,
354
 
                                     _("Set picked color"));
 
319
                    DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_DROPPER,
 
320
                                       _("Set picked color"));
355
321
                }
356
322
 
357
323
                ret = TRUE;