~ubuntu-branches/ubuntu/vivid/gimp/vivid

« back to all changes in this revision

Viewing changes to plug-ins/imagemap/imap_preview.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach
  • Date: 2012-05-08 18:50:03 UTC
  • mto: (1.1.26) (0.5.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 71.
  • Revision ID: package-import@ubuntu.com-20120508185003-tltkvbaysf8d2426
ImportĀ upstreamĀ versionĀ 2.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * Copyright (C) 1998-2005 Maurits Rijk  m.rijk@chello.nl
7
7
 *
8
 
 * This program is free software; you can redistribute it and/or modify
 
8
 * This program is free software: you can redistribute it and/or modify
9
9
 * it under the terms of the GNU General Public License as published by
10
 
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * the Free Software Foundation; either version 3 of the License, or
11
11
 * (at your option) any later version.
12
12
 *
13
13
 * This program is distributed in the hope that it will be useful,
16
16
 * GNU General Public License for more details.
17
17
 *
18
18
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program; if not, write to the Free Software
20
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
20
 *
22
21
 */
23
22
 
36
35
#include "imap_preview.h"
37
36
 
38
37
#define PREVIEW_MASK  (GDK_EXPOSURE_MASK       | \
39
 
                       GDK_POINTER_MOTION_MASK | \
 
38
                       GDK_POINTER_MOTION_MASK | \
40
39
                       GDK_BUTTON_PRESS_MASK   | \
41
 
                       GDK_BUTTON_RELEASE_MASK | \
42
 
                       GDK_BUTTON_MOTION_MASK  | \
43
 
                       GDK_KEY_PRESS_MASK      | \
44
 
                       GDK_KEY_RELEASE_MASK    | \
45
 
                       GDK_ENTER_NOTIFY_MASK   | \
46
 
                       GDK_LEAVE_NOTIFY_MASK)
 
40
                       GDK_BUTTON_RELEASE_MASK | \
 
41
                       GDK_BUTTON_MOTION_MASK  | \
 
42
                       GDK_KEY_PRESS_MASK      | \
 
43
                       GDK_KEY_RELEASE_MASK    | \
 
44
                       GDK_ENTER_NOTIFY_MASK   | \
 
45
                       GDK_LEAVE_NOTIFY_MASK)
47
46
 
48
47
#define PREVIEW_SIZE 400
49
48
 
50
49
/*======================================================================
51
 
                Preview Rendering Util routine
 
50
                Preview Rendering Util routine
52
51
=======================================================================*/
53
52
 
54
53
#define CHECKWIDTH 4
55
54
#define LIGHTCHECK 192
56
55
#define DARKCHECK  128
57
56
#ifndef OPAQUE
58
 
#define OPAQUE     255
 
57
#define OPAQUE     255
59
58
#endif
60
59
 
 
60
static Object_t *_tmp_obj;
 
61
 
61
62
static Preview_t*
62
63
preview_user_data(GtkWidget *preview)
63
64
{
79
80
static void
80
81
render_gray_image(Preview_t *preview_base, GimpPixelRgn *srcrgn)
81
82
{
82
 
   guchar        *src_row, *dest_buffer, *src, *dest;
83
 
   gint          row, col;
84
 
   gint          bpp, dwidth, dheight, pwidth, pheight;
85
 
   gint          *src_col;
 
83
   guchar        *src_row, *dest_buffer, *dest;
 
84
   gint          row, col;
 
85
   gint          bpp, dwidth, dheight, pwidth, pheight;
 
86
   gint          *src_col;
86
87
   GtkWidget     *preview = preview_base->preview;
87
88
 
88
89
   dwidth  = srcrgn->w;
102
103
 
103
104
   for (row = 0; row < pheight; row++) {
104
105
      gimp_pixel_rgn_get_row(srcrgn, src_row, 0, row * dheight / pheight,
105
 
                             dwidth);
106
 
 
107
 
      src = src_row;
 
106
                             dwidth);
108
107
 
109
108
      for (col = 0; col < pwidth; col++) {
110
 
         src = &src_row[src_col[col]];
111
 
         *dest++ = *src;
 
109
         guchar *src;
 
110
         src = &src_row[src_col[col]];
 
111
         *dest++ = *src;
112
112
      }
113
113
   }
114
114
   gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
125
125
static void
126
126
render_indexed_image(Preview_t *preview_base, GimpPixelRgn *srcrgn)
127
127
{
128
 
   guchar        *src_row, *dest_buffer, *src, *dest;
129
 
   gint          row, col;
130
 
   gint          dwidth, dheight, pwidth, pheight;
131
 
   gint          *src_col;
132
 
   gint          bpp, alpha, has_alpha;
133
 
   guchar        *cmap, *colour;
134
 
   gint          ncols;
135
 
   gboolean      gray = get_map_info()->show_gray;
 
128
   guchar        *src_row, *dest_buffer, *src, *dest;
 
129
   gint          row, col;
 
130
   gint          dwidth, dheight, pwidth, pheight;
 
131
   gint          *src_col;
 
132
   gint          bpp, alpha, has_alpha;
 
133
   guchar        *cmap, *colour;
 
134
   gint          ncols;
 
135
   gboolean      gray = get_map_info()->show_gray;
136
136
   GtkWidget    *preview = preview_base->preview;
137
137
 
138
138
   dwidth  = srcrgn->w;
145
145
   if (has_alpha)
146
146
      alpha--;
147
147
 
148
 
   cmap = gimp_image_get_colormap (gimp_drawable_get_image (srcrgn->drawable->drawable_id),
 
148
   cmap = gimp_image_get_colormap (gimp_item_get_image (srcrgn->drawable->drawable_id),
149
149
                                   &ncols);
150
150
 
151
151
   src_row = g_new(guchar, dwidth * bpp);
158
158
   dest = dest_buffer;
159
159
   for (row = 0; row < pheight; row++) {
160
160
      gimp_pixel_rgn_get_row(srcrgn, src_row, 0, row * dheight / pheight,
161
 
                             dwidth);
 
161
                             dwidth);
162
162
 
163
163
      for (col = 0; col < pwidth; col++) {
164
 
         src = &src_row[src_col[col]];
165
 
         colour = cmap + 3 * (int)(*src);
 
164
         src = &src_row[src_col[col]];
 
165
         colour = cmap + 3 * (int)(*src);
166
166
 
167
 
         if (gray) {
168
 
            guchar avg = (299 * colour[0] + 587 * colour[1] +
169
 
                          114 * colour[2]) / 1000;
170
 
            *dest++ = avg;
171
 
            *dest++ = avg;
172
 
            *dest++ = avg;
173
 
         } else {
174
 
            *dest++ = colour[0];
175
 
            *dest++ = colour[1];
176
 
            *dest++ = colour[2];
177
 
         }
 
167
         if (gray) {
 
168
            guchar avg = (299 * colour[0] + 587 * colour[1] +
 
169
                          114 * colour[2]) / 1000;
 
170
            *dest++ = avg;
 
171
            *dest++ = avg;
 
172
            *dest++ = avg;
 
173
         } else {
 
174
            *dest++ = colour[0];
 
175
            *dest++ = colour[1];
 
176
            *dest++ = colour[2];
 
177
         }
178
178
      }
179
179
   }
180
180
   gimp_preview_area_draw(GIMP_PREVIEW_AREA(preview),
190
190
static void
191
191
render_rgb_image(Preview_t *preview_base, GimpPixelRgn *srcrgn)
192
192
{
193
 
   guchar        *src_row, *dest_buffer, *src, *dest;
194
 
   gint          row, col;
195
 
   gint          dwidth, dheight, pwidth, pheight;
196
 
   gint          *src_col;
197
 
   gint          bpp, alpha, has_alpha, b;
198
 
   guchar        check;
199
 
   gboolean      gray = get_map_info()->show_gray;
 
193
   guchar        *src_row, *dest_buffer, *src, *dest;
 
194
   gint          row, col;
 
195
   gint          dwidth, dheight, pwidth, pheight;
 
196
   gint          *src_col;
 
197
   gint          bpp, alpha, has_alpha, b;
 
198
   guchar        check;
 
199
   gboolean      gray = get_map_info()->show_gray;
200
200
   GtkWidget    *preview = preview_base->preview;
201
201
 
202
202
   dwidth  = srcrgn->w;
219
219
   dest = dest_buffer;
220
220
   for (row = 0; row < pheight; row++) {
221
221
      gimp_pixel_rgn_get_row(srcrgn, src_row, 0, row * dheight / pheight,
222
 
                             dwidth);
 
222
                             dwidth);
223
223
      for (col = 0; col < pwidth; col++) {
224
 
         src = &src_row[src_col[col]];
225
 
         if(!has_alpha || src[alpha] == OPAQUE) {
226
 
            /* no alpha channel or opaque -- simple way */
227
 
            for (b = 0; b < alpha; b++)
228
 
               dest[b] = src[b];
229
 
         } else {
230
 
            /* more or less transparent */
231
 
            if( ( col % (CHECKWIDTH*2) < CHECKWIDTH ) ^
232
 
                ( row % (CHECKWIDTH*2) < CHECKWIDTH ) )
233
 
               check = LIGHTCHECK;
234
 
            else
235
 
               check = DARKCHECK;
 
224
         src = &src_row[src_col[col]];
 
225
         if(!has_alpha || src[alpha] == OPAQUE) {
 
226
            /* no alpha channel or opaque -- simple way */
 
227
            for (b = 0; b < alpha; b++)
 
228
               dest[b] = src[b];
 
229
         } else {
 
230
            /* more or less transparent */
 
231
            if( ( col % (CHECKWIDTH*2) < CHECKWIDTH ) ^
 
232
                ( row % (CHECKWIDTH*2) < CHECKWIDTH ) )
 
233
               check = LIGHTCHECK;
 
234
            else
 
235
               check = DARKCHECK;
236
236
 
237
 
            if (src[alpha] == 0) {
238
 
               /* full transparent -- check */
239
 
               for (b = 0; b < alpha; b++)
240
 
                  dest[b] = check;
241
 
            } else {
242
 
               /* middlemost transparent -- mix check and src */
243
 
               for (b = 0; b < alpha; b++)
244
 
                  dest[b] = (src[b] * src[alpha] +
245
 
                             check * (OPAQUE - src[alpha])) / OPAQUE;
246
 
            }
247
 
         }
248
 
         if (gray) {
249
 
            guchar avg;
250
 
            avg = (299 * dest[0] + 587 * dest[1] + 114 * dest[2]) / 1000;
251
 
            for (b = 0; b < alpha; b++)
252
 
               dest[b] = avg;
253
 
         }
254
 
         dest += alpha;
 
237
            if (src[alpha] == 0) {
 
238
               /* full transparent -- check */
 
239
               for (b = 0; b < alpha; b++)
 
240
                  dest[b] = check;
 
241
            } else {
 
242
               /* middlemost transparent -- mix check and src */
 
243
               for (b = 0; b < alpha; b++)
 
244
                  dest[b] = (src[b] * src[alpha] +
 
245
                             check * (OPAQUE - src[alpha])) / OPAQUE;
 
246
            }
 
247
         }
 
248
         if (gray) {
 
249
            guchar avg;
 
250
            avg = (299 * dest[0] + 587 * dest[1] + 114 * dest[2]) / 1000;
 
251
            for (b = 0; b < alpha; b++)
 
252
               dest[b] = avg;
 
253
         }
 
254
         dest += alpha;
255
255
      }
256
256
   }
257
257
   gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
294
294
static gboolean
295
295
preview_expose(GtkWidget *widget, GdkEventExpose *event)
296
296
{
297
 
   draw_grid(widget);
298
 
   draw_shapes(widget);
 
297
   cairo_t *cr;
 
298
   gint width = preview_get_width (widget);
 
299
   gint height = preview_get_height (widget);
 
300
 
 
301
   cr = gdk_cairo_create (event->window);
 
302
   gdk_cairo_region (cr, event->region);
 
303
   cairo_clip (cr);
 
304
   cairo_set_line_width (cr, 1.);
 
305
   draw_grid (cr, width, height);
 
306
   
 
307
   draw_shapes (cr);
 
308
 
 
309
   if (_tmp_obj)
 
310
   {
 
311
      /* this is a bit of a hack */
 
312
      gdouble dash = 4.;
 
313
      _tmp_obj->selected |= 4;
 
314
      cairo_set_source_rgb (cr, 1., 0., 1.);
 
315
      cairo_set_dash (cr, &dash, 1, dash);
 
316
      object_draw (_tmp_obj, cr);
 
317
   }
 
318
 
 
319
   cairo_destroy (cr);
299
320
   return FALSE;
300
321
}
301
322
 
302
323
void
303
 
add_preview_motion_event(Preview_t *preview, GCallback func)
304
 
{
305
 
   g_return_if_fail (func != NULL);
306
 
 
307
 
   g_signal_connect(preview->preview, "motion-notify-event",
308
 
                    func, NULL);
309
 
}
310
 
 
311
 
void
312
 
add_enter_notify_event(Preview_t *preview, GCallback func)
313
 
{
314
 
   g_return_if_fail (func != NULL);
315
 
 
316
 
   g_signal_connect(preview->preview, "enter-notify-event",
317
 
                    func, NULL);
318
 
}
319
 
 
320
 
void
321
 
add_leave_notify_event(Preview_t *preview, GCallback func)
322
 
{
323
 
   g_return_if_fail (func != NULL);
324
 
 
325
 
   g_signal_connect(preview->preview, "leave-notify-event",
326
 
                    func, NULL);
327
 
}
328
 
 
329
 
void
330
 
add_preview_button_press_event(Preview_t *preview, GCallback func)
331
 
{
332
 
   g_return_if_fail (func != NULL);
333
 
 
334
 
   g_signal_connect(preview->preview, "button-press-event",
335
 
                    func, NULL);
336
 
}
337
 
 
338
 
void
339
 
preview_redraw(Preview_t *preview)
340
 
{
341
 
  gtk_widget_queue_draw(preview->preview);
 
324
preview_set_tmp_obj (Object_t *obj)
 
325
{
 
326
   _tmp_obj = obj;
 
327
}
 
328
 
 
329
void
 
330
preview_unset_tmp_obj (Object_t *obj)
 
331
{
 
332
   if (_tmp_obj == obj) _tmp_obj = NULL;
342
333
}
343
334
 
344
335
void
350
341
                                preview->widget_height);
351
342
   gtk_widget_queue_resize(preview->window);
352
343
   render_preview(preview, &preview->src_rgn);
353
 
   preview_redraw(preview);
 
344
   preview_redraw();
354
345
}
355
346
 
356
347
GdkCursorType
361
352
   GdkCursor     *cursor      = gdk_cursor_new_for_display (display,
362
353
                                                            cursor_type);
363
354
 
364
 
   gdk_window_set_cursor(preview->window->window, cursor);
 
355
   gdk_window_set_cursor(gtk_widget_get_window (preview->window), cursor);
365
356
   gdk_cursor_unref(cursor);
366
357
 
367
358
   preview->cursor = cursor_type;
377
368
 
378
369
static void
379
370
handle_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
380
 
            GtkSelectionData *data, guint info, guint time)
 
371
            GtkSelectionData *data, guint info, guint time)
381
372
{
382
 
   gboolean success = FALSE;
383
 
   if (data->length >= 0 && data->format == 8) {
 
373
  gboolean success = FALSE;
 
374
 
 
375
  if (gtk_selection_data_get_length (data) >= 0 &&
 
376
      gtk_selection_data_get_format (data) == 8)
 
377
    {
384
378
      ObjectList_t *list = get_shapes();
385
379
      Object_t *obj;
386
380
 
387
381
      x = get_real_coord(x);
388
382
      y = get_real_coord(y);
389
383
      obj = object_list_find(list, x, y);
390
 
      if (obj && !obj->locked) {
391
 
         command_list_add(edit_object_command_new(obj));
392
 
         object_set_url(obj, (const gchar *) data->data);
393
 
         object_emit_update_signal(obj);
394
 
         success = TRUE;
395
 
      }
396
 
   }
397
 
   gtk_drag_finish(context, success, FALSE, time);
 
384
      if (obj && !obj->locked)
 
385
        {
 
386
          command_list_add(edit_object_command_new(obj));
 
387
          object_set_url(obj, (const gchar *) gtk_selection_data_get_data (data));
 
388
          object_emit_update_signal(obj);
 
389
          success = TRUE;
 
390
        }
 
391
    }
 
392
  gtk_drag_finish(context, success, FALSE, time);
398
393
}
399
394
 
400
395
static void
412
407
                    GimpRuler     *ruler)
413
408
{
414
409
  gimp_ruler_set_range (ruler,
415
 
                        adj->value, adj->value + adj->page_size, adj->upper);
 
410
                        gtk_adjustment_get_value (adj),
 
411
                        gtk_adjustment_get_value (adj) +
 
412
                        gtk_adjustment_get_page_size (adj),
 
413
                        gtk_adjustment_get_upper (adj));
416
414
}
417
415
 
418
416
Preview_t *
435
433
   g_object_set_data (G_OBJECT (preview), "preview", data);
436
434
   gtk_widget_set_events(GTK_WIDGET(preview), PREVIEW_MASK);
437
435
   g_signal_connect_after(preview, "expose-event",
438
 
                          G_CALLBACK(preview_expose), data);
 
436
                          G_CALLBACK(preview_expose), data);
439
437
   g_signal_connect (preview, "size-allocate",
440
438
                     G_CALLBACK (preview_size_allocate), (gpointer)data);
441
439
 
442
440
   /* Handle drop of links in preview widget */
443
441
   gtk_drag_dest_set(preview, GTK_DEST_DEFAULT_ALL, target_table,
444
 
                     2, GDK_ACTION_COPY);
 
442
                     2, GDK_ACTION_COPY);
445
443
   g_signal_connect(preview, "drag-data-received",
446
 
                    G_CALLBACK(handle_drop), NULL);
 
444
                    G_CALLBACK(handle_drop), NULL);
447
445
 
448
446
   data->widget_width = data->width =
449
447
       gimp_drawable_width(drawable->drawable_id);
459
457
 
460
458
   /* Create button with arrow */
461
459
   button = gtk_button_new();
462
 
   GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS);
 
460
   gtk_widget_set_can_focus (button, FALSE);
463
461
   gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 1, GTK_FILL, GTK_FILL,
464
 
                    0, 0);
 
462
                    0, 0);
465
463
   gtk_widget_set_events(button,
466
 
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
 
464
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
467
465
   g_signal_connect(button, "button-press-event",
468
 
                    G_CALLBACK(arrow_cb), NULL);
 
466
                    G_CALLBACK(arrow_cb), NULL);
469
467
   gtk_widget_show(button);
470
468
 
471
469
   arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
475
473
   /* Create horizontal ruler */
476
474
   data->hruler = ruler = gimp_ruler_new (GTK_ORIENTATION_HORIZONTAL);
477
475
   g_signal_connect_swapped(preview, "motion-notify-event",
478
 
                            G_CALLBACK(GTK_WIDGET_GET_CLASS(ruler)->motion_notify_event),
479
 
                            ruler);
 
476
                            G_CALLBACK(GTK_WIDGET_GET_CLASS(ruler)->motion_notify_event),
 
477
                            ruler);
480
478
 
481
479
   gtk_table_attach(GTK_TABLE(table), ruler, 1, 2, 0, 1,
482
480
                    GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
485
483
   /* Create vertical ruler */
486
484
   data->vruler = ruler = gimp_ruler_new (GTK_ORIENTATION_VERTICAL);
487
485
   g_signal_connect_swapped(preview, "motion-notify-event",
488
 
                            G_CALLBACK(GTK_WIDGET_GET_CLASS(ruler)->motion_notify_event),
489
 
                            ruler);
 
486
                            G_CALLBACK(GTK_WIDGET_GET_CLASS(ruler)->motion_notify_event),
 
487
                            ruler);
490
488
   gtk_table_attach(GTK_TABLE(table), ruler, 0, 1, 1, 2,
491
489
                    GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
492
490
   gtk_widget_show(ruler);
493
491
 
494
492
   window = gtk_scrolled_window_new (NULL, NULL);
495
493
   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(window),
496
 
                                  GTK_POLICY_NEVER, GTK_POLICY_NEVER);
 
494
                                  GTK_POLICY_NEVER, GTK_POLICY_NEVER);
497
495
   width = (data->width > 600) ? 600 : data->width;
498
496
   height = (data->height > 400) ? 400 : data->height;
499
497
   gtk_widget_set_size_request(window, width, height);
500
498
   gtk_table_attach(GTK_TABLE(table), window, 1, 2, 1, 2, GTK_FILL, GTK_FILL,
501
 
                    0, 0);
 
499
                    0, 0);
502
500
   gtk_widget_show(window);
503
501
 
504
502
   hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (window));
521
519
 
522
520
   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(window), preview);
523
521
 
524
 
   scrollbar = gtk_hscrollbar_new (hadj);
 
522
   scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, hadj);
525
523
   gtk_table_attach(GTK_TABLE(table), scrollbar, 1, 2, 2, 3,
526
524
                    GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
527
525
   gtk_widget_show (scrollbar);
528
526
 
529
 
   scrollbar = gtk_vscrollbar_new (vadj);
 
527
   scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, vadj);
530
528
   gtk_table_attach(GTK_TABLE(table), scrollbar,  2, 3, 1, 2,
531
529
                    GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
532
530
   gtk_widget_show (scrollbar);
534
532
   gtk_widget_show (preview);
535
533
 
536
534
   gimp_pixel_rgn_init(&data->src_rgn, drawable, 0, 0, data->width,
537
 
                       data->height, FALSE, FALSE);
 
535
                       data->height, FALSE, FALSE);
538
536
   render_preview(data, &data->src_rgn);
539
537
 
540
538
   gtk_widget_show(table);