1 /* pisa_preview_window.cc
2 Copyright (C) 2001, 2004, 2005, 2008 SEIKO EPSON Corporation
3
4 This file is part of the `iscan' program.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 As a special exception, the copyright holders give permission
21 to link the code of this program with the esmod library and
22 distribute linked combinations including the two. You must obey
23 the GNU General Public License in all respects for all of the
24 code used other then esmod.
25 */
26
27 /*------------------------------------------------------------*/
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 /*------------------------------------------------------------*/
33 #include "pisa_view_manager.h"
34 #include "pisa_preview_window.h"
35 #include "pisa_error.h"
36 #include "pisa_scan_tool.h"
37 #include "pisa_tool.h"
38 #include "pisa_default_val.h"
39 #include "pisa_aleart_dialog.h"
40 #include "pisa_change_unit.h"
41
42 /*------------------------------------------------------------*/
43 long g_prev_max_x = 320;
44 long g_prev_max_y = 440;
45
46 const double g_min_marq_size = 0.4;
47
48 /*------------------------------------------------------------*/
expose_event(GtkWidget * widget,GdkEventExpose * event)49 static gint expose_event ( GtkWidget * widget,
50 GdkEventExpose * event )
51 {
52 preview_window * prev_cls;
53
54 prev_cls = ( preview_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_PREV );
55
56 return prev_cls->expose_event ( widget, event );
57 }
58
59
60 /*------------------------------------------------------------*/
event(GtkWidget * widget,GdkEvent * event)61 static gint event ( GtkWidget * widget,
62 GdkEvent * event )
63 {
64 preview_window * prev_cls;
65
66 prev_cls = ( preview_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_PREV );
67
68 return prev_cls->event ( widget, event );
69 }
70
71 /*------------------------------------------------------------*/
size_allocate(GtkWidget * widget)72 static void size_allocate ( GtkWidget * widget )
73 {
74 preview_window * prev_cls;
75
76 prev_cls = ( preview_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_PREV );
77
78 prev_cls->size_allocate ( widget );
79 }
80
81 /*------------------------------------------------------------*/
init(void)82 int preview_window::init ( void )
83 {
84 int i;
85
86 m_gc = 0;
87
88 m_img_width = g_prev_max_x;
89 m_img_height = g_prev_max_y;
90
91 m_is_prev = 0;
92 m_drag = 0;
93
94 m_img = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
95
96 if ( m_img == 0 )
97 return PISA_ERR_OUTOFMEMORY;
98
99 m_img_org = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
100
101 if ( m_img_org == 0 )
102 {
103 delete [ ] m_img;
104 m_img = 0;
105 return PISA_ERR_OUTOFMEMORY;
106 }
107
108 for ( i = 0; i < 11; i++ )
109 m_cursor [ i ] = 0;
110
111 m_on_preview = false;
112 m_allocate_width = 0;
113 m_allocate_height = 0;
114
115 return PISA_ERR_SUCCESS;
116 }
117
118 /*------------------------------------------------------------*/
create_window(GtkWidget * parent)119 GtkWidget * preview_window::create_window ( GtkWidget * parent )
120 {
121 m_win = create_darea ( parent );
122
123 create_cursor ( );
124
125 return m_win;
126 }
127
128 /*------------------------------------------------------------*/
close_window(int destroy)129 int preview_window::close_window ( int destroy )
130 {
131 destroy = destroy;
132
133 if ( m_gc )
134 {
135 ::gdk_gc_destroy ( m_gc );
136 m_gc = 0;
137 }
138
139 if ( m_img )
140 {
141 delete [ ] m_img;
142 m_img = 0;
143 }
144
145 if ( m_img_org )
146 {
147 delete [ ] m_img_org;
148 m_img_org = 0;
149 }
150
151 return PISA_ERR_SUCCESS;
152 }
153
154 /*------------------------------------------------------------*/
resize_window(void)155 int preview_window::resize_window ( void )
156 {
157 get_preview_resolution ( );
158 resize_preview_window ( 0, 0 );
159
160 clear_image ( );
161
162 return 0;
163 }
164
165 /*------------------------------------------------------------*/
auto_exposure(void)166 int preview_window::auto_exposure ( void )
167 {
168 pisa_image_info info;
169 _rectL region;
170 marquee tmp_marq, * marq;
171 int i, marq_num;
172
173 scan_manager *scan_mgr = g_view_manager->get_scan_manager ();
174
175 if ( m_is_prev == 0 ||
176 g_view_manager->get_settings ().imgtype.pixeltype == PISA_PT_BW )
177 {
178 return PISA_ERR_SUCCESS;
179 }
180
181 info.m_img = m_img_org;
182 info.m_width = m_img_width;
183 info.m_height = m_img_height;
184 info.m_rowbytes = g_prev_max_x * 3;
185
186 marq_num = g_view_manager->get_marquee_size ();
187 marq = & g_view_manager->get_marquee ();
188
189 if ( marq_num < 2 )
190 {
191 region.left = 0;
192 region.top = 0;
193 region.right = m_img_width - 1;
194 region.bottom = m_img_height - 1;
195 }
196 else
197 {
198 _pointL pt_lt, pt_rb;
199
200 get_marquee_point ( marq_num - 1, & pt_lt, & pt_rb );
201
202 region.left = pt_lt.x;
203 region.top = pt_lt.y;
204 region.right = pt_rb.x;
205 region.bottom = pt_rb.y;
206 }
207
208 settings set = g_view_manager->get_settings ();
209 iscan::auto_expose (set.option,
210 set.film,
211 & info,
212 & region,
213 & tmp_marq,
214 set.imgtype.ae_option != PISA_AE_DOC,
215 scan_mgr->is_dumb ());
216
217 marq->gamma = tmp_marq.gamma;
218 marq->highlight = tmp_marq.highlight;
219 marq->shadow = tmp_marq.shadow;
220 marq->graybalance = tmp_marq.graybalance;
221
222 for ( i = 0; i < 3; i++ )
223 {
224 marq->film_gamma [ i ] = tmp_marq.film_gamma [ i ];
225 marq->film_yp [ i ] = tmp_marq.film_yp [ i ];
226 marq->grayl [ i ] = tmp_marq.grayl [ i ];
227 }
228
229 ::g_view_manager->sensitive ( );
230 ::g_view_manager->update_lut ( );
231
232 return PISA_ERR_SUCCESS;
233 }
234
235 /*------------------------------------------------------------*/
update_img(bool left)236 int preview_window::update_img ( bool left )
237 {
238 int i;
239 pisa_image_info img_info;
240 marquee * marq;
241 double delta;
242 long curr_width, adj_width, resolution;
243
244 if ( m_is_prev == 0 )
245 {
246 clear_image ( );
247 return PISA_ERR_SUCCESS;
248 }
249
250 settings set = g_view_manager->get_settings ();
251 marq = & g_view_manager->get_marquee ();
252
253 resolution = (set.resolution * (marq->scale)) / 100;
254 curr_width = ::inch2pixel ( marq->area.x, resolution );
255 adj_width = ::inch2width ( marq->area.x, resolution );
256 delta = marq->area.x - (marq->area.x) * adj_width /curr_width ;
257
258 // Resize the area
259 marq -> area.x -= delta;
260 if ( left )
261 {
262 // If the left side -> increase the x offset
263 marq ->offset.x += delta;
264 }
265
266 if ( m_img == 0 || m_img_org == 0 )
267 return PISA_ERR_OUTOFMEMORY;
268
269 ::memcpy ( m_img, m_img_org, g_prev_max_x * g_prev_max_y * 3 );
270
271 img_info.m_img = m_img;
272 img_info.m_width = m_img_width;
273 img_info.m_height = m_img_height;
274 img_info.m_rowbytes = g_prev_max_x * 3;
275
276 ::tool_lut ( & img_info, & marq->lut );
277
278 switch (set.imgtype.pixeltype)
279 {
280 case PISA_PT_RGB:
281 tool_matrix (&img_info, marq->saturation, set.coef);
282 if (set.usm)
283 tool_usm (img_info);
284 break;
285
286 case PISA_PT_GRAY:
287 build_gray (&img_info, set.imgtype.dropout);
288 if (set.usm)
289 tool_usm (img_info);
290 break;
291
292 case PISA_PT_BW:
293 build_bw (&img_info,
294 set.imgtype.dropout,
295 set.imgtype.halftone,
296 marq->threshold);
297 break;
298 }
299
300 for ( i = 0; i < m_img_height; i++ )
301 ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ),
302 m_img + i * g_prev_max_x * 3,
303 0, i, m_img_width );
304
305 ::gtk_widget_draw ( m_prev, 0 );
306 ::gdk_flush ( );
307
308 return PISA_ERR_SUCCESS;
309 }
310
311 /*--------------------------------------------------------------*/
start_preview(pisa_preview_type type)312 void preview_window::start_preview ( pisa_preview_type type )
313 {
314 scan_manager * scan_mgr;
315 int width, height;
316 int cancel;
317
318 cancel = 0;
319
320 m_is_prev = 0;
321
322 m_on_preview = true;
323 m_allocate_width = 0;
324 m_allocate_height = 0;
325
326 progress_window feedback
327 (static_cast <main_window *> (g_view_manager
328 ->get_window_cls (ID_WINDOW_MAIN))
329 ->get_widget());
330 feedback.set_text (progress_window::WARMING_UP);
331 feedback.show ();
332
333 while ( ::gtk_events_pending ( ) )
334 ::gtk_main_iteration ( );
335
336 // preview
337 scan_mgr = g_view_manager->get_scan_manager ( );
338 set_preview_param (type);
339
340 reset_settings ( type );
341 ::g_view_manager->sensitive ( );
342
343 try
344 {
345 scan_mgr->init_scan (&width, &height);
346
347 if ( type == PISA_PREV_WHOLE )
348 {
349 change_max_scan_area ( width, height );
350 ::g_view_manager->sensitive ( );
351 }
352
353 resize_preview_window ( width, height );
354 clear_image ( );
355
356 while ( ::gtk_events_pending ( ) )
357 ::gtk_main_iteration ( );
358
359 for (int i = 0; i < height; i++ )
360 {
361 scan_mgr->acquire_image ( m_img_org + i * g_prev_max_x * 3,
362 width * 3,
363 1,
364 cancel );
365
366 if ( i == 0 )
367 feedback.set_text (progress_window::PREVIEWING);
368
369 if (cancel)
370 break;
371
372 feedback.set_progress (i, height);
373 cancel = feedback.is_cancelled ();
374
375 ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ),
376 m_img_org + i * g_prev_max_x * 3,
377 0, i, width );
378 if ( i % 20 == 0 )
379 {
380 ::gtk_preview_put ( GTK_PREVIEW ( m_prev ),
381 m_prev->window,
382 m_prev->style->black_gc,
383 0, 0, 0, 0, width, height );
384 }
385
386 while ( ::gtk_events_pending ( ) )
387 ::gtk_main_iteration ( );
388 }
389 feedback.set_progress (height, height);
390 cancel = feedback.is_cancelled ();
391 if (cancel)
392 {
393 m_on_preview = false;
394 update_img ( );
395 change_max_disp_area ( m_allocate_width, m_allocate_height );
396 m_allocate_width = 0;
397 m_allocate_height = 0;
398 }
399 else
400 {
401 m_is_prev = 1;
402 ::gtk_widget_draw ( m_prev, 0 );
403 ::gdk_flush ( );
404
405 m_on_preview = false;
406
407 auto_exposure ( );
408 update_img ( );
409 change_max_disp_area ( m_allocate_width, m_allocate_height );
410 m_allocate_width = 0;
411 m_allocate_height = 0;
412 }
413 }
414 catch ( const pisa_error & err )
415 {
416 main_window * main_cls;
417 aleart_dialog aleart_dlg;
418
419 main_cls = ( main_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_MAIN );
420 aleart_dlg.message_box ( main_cls->get_widget ( ),
421 err.get_error_string ( ) );
422
423 delete_marquee ( );
424
425 m_on_preview = false;
426 update_img ( );
427 change_max_disp_area ( m_allocate_width, m_allocate_height );
428 m_allocate_width = 0;
429 m_allocate_height = 0;
430 }
431
432 scan_mgr->finish_acquire ( );
433
434 ::g_view_manager->sensitive ( );
435
436 {
437 gint x, y;
438 ::gdk_window_get_pointer ( m_prev->window, & x, & y, 0 );
439 set_mouse_cursor ( x, y );
440 change_cursor ( );
441 }
442 }
443
444 /*--------------------------------------------------------------*/
expose_event(GtkWidget * widget,GdkEventExpose * event)445 gint preview_window::expose_event ( GtkWidget * widget,
446 GdkEventExpose * event )
447 {
448 widget = widget;
449 event = event;
450
451 draw_marquee ( );
452
453 return FALSE;
454 }
455
456 /*--------------------------------------------------------------*/
event(GtkWidget * widget,GdkEvent * event)457 gint preview_window::event ( GtkWidget * widget, GdkEvent * event )
458 {
459 gint ret;
460
461 widget = widget;
462
463 switch ( event->type )
464 {
465 case GDK_EXPOSE:
466 if ( m_gc )
467 {
468 draw_marquee ( );
469 }
470 ret = FALSE;
471 break;
472
473 case GDK_BUTTON_PRESS:
474 ret = mouse_down ( event );
475 ::gtk_grab_add ( widget );
476 break;
477
478 case GDK_MOTION_NOTIFY:
479 ret = mouse_move ( event );
480 break;
481
482 case GDK_BUTTON_RELEASE:
483 ret = mouse_up ( event );
484 ::gtk_grab_remove ( widget );
485 break;
486
487 default:
488 ret = TRUE;
489 break;
490 }
491
492 return ret;
493 }
494
495 /*------------------------------------------------------------*/
size_allocate(GtkWidget * widget)496 void preview_window::size_allocate ( GtkWidget * widget )
497 {
498 int x, y;
499
500 x = widget->allocation.width;
501 y = widget->allocation.height;
502
503 if ( m_on_preview )
504 {
505 m_allocate_width = x;
506 m_allocate_height = y;
507 return;
508 }
509
510 change_max_disp_area ( x, y );
511 }
512
513
514 /*------------------------------------------------------------*/
create_darea(GtkWidget * parent)515 GtkWidget * preview_window::create_darea ( GtkWidget * parent )
516 {
517 GtkWidget * frame;
518
519 parent = parent;
520
521 frame = ::gtk_frame_new ( 0 );
522 ::gtk_frame_set_shadow_type ( GTK_FRAME ( frame ), GTK_SHADOW_IN );
523 ::gtk_container_border_width ( GTK_CONTAINER ( frame ), 3 );
524
525 m_prev = ::gtk_preview_new ( GTK_PREVIEW_COLOR );
526 ::gtk_preview_set_expand ( GTK_PREVIEW ( m_prev ), TRUE );
527
528 // set size of preview window
529 get_preview_resolution ( );
530 resize_preview_window ( m_img_width, m_img_height );
531
532 ::gtk_container_add ( GTK_CONTAINER ( frame ), m_prev );
533 ::gtk_widget_show ( m_prev );
534
535 clear_image ( );
536
537 // signals
538 ::gtk_signal_connect ( GTK_OBJECT ( m_prev ), "event",
539 GTK_SIGNAL_FUNC ( ::event ), 0 );
540 ::gtk_signal_connect_after ( GTK_OBJECT ( m_prev ), "expose_event",
541 GTK_SIGNAL_FUNC ( ::expose_event ), 0 );
542 ::gtk_signal_connect_after ( GTK_OBJECT ( m_prev ), "size_allocate",
543 GTK_SIGNAL_FUNC ( ::size_allocate ), 0 );
544
545 ::gtk_widget_set_events ( m_prev ,
546 GDK_EXPOSURE_MASK |
547 GDK_LEAVE_NOTIFY_MASK |
548 GDK_BUTTON_PRESS_MASK |
549 GDK_POINTER_MOTION_MASK |
550 GDK_POINTER_MOTION_HINT_MASK |
551 GDK_BUTTON_RELEASE_MASK );
552
553 return frame;
554 }
555
556
557 /*------------------------------------------------------------*/
get_preview_resolution(const _rectD * img_rect)558 long preview_window::get_preview_resolution ( const _rectD * img_rect )
559 {
560 long resolution;
561 _pointD pt_scan_size;
562 double aspect_max;
563 double aspect_scan;
564
565 if ( img_rect )
566 {
567 pt_scan_size.x = img_rect->right - img_rect->left;
568 pt_scan_size.y = img_rect->bottom - img_rect->top;
569 m_img_rect = * img_rect;
570 }
571 else
572 {
573 pt_scan_size.x = g_view_manager->get_settings ().max_area [ 0 ];
574 pt_scan_size.y = g_view_manager->get_settings ().max_area [ 1 ];
575
576 m_img_rect.left = 0.0;
577 m_img_rect.top = 0.0;
578 m_img_rect.right = pt_scan_size.x;
579 m_img_rect.bottom = pt_scan_size.y;
580 }
581
582 aspect_max = ( float ) g_prev_max_y / g_prev_max_x;
583 aspect_scan = ( float ) pt_scan_size.y / pt_scan_size.x;
584
585 if ( aspect_max < aspect_scan )
586 resolution = ( long ) ( g_prev_max_y / pt_scan_size.y );
587 else
588 resolution = ( long ) ( g_prev_max_x / pt_scan_size.x );
589
590 m_img_width = ( long ) ( resolution * pt_scan_size.x );
591 m_img_height = ( long ) ( resolution * pt_scan_size.y );
592
593 return resolution;
594 }
595
596 /*------------------------------------------------------------*/
resize_preview_window(long width,long height)597 void preview_window::resize_preview_window ( long width, long height )
598 {
599 if ( width != 0 && height != 0 )
600 {
601 m_img_width = width;
602 m_img_height = height;
603 }
604
605 if ( m_img )
606 {
607 delete [ ] m_img;
608 m_img = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
609 }
610
611 if ( m_img_org )
612 {
613 delete [ ] m_img_org;
614 m_img_org = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
615 }
616
617 m_client_rect.left = 0;
618 m_client_rect.top = 0;
619 m_client_rect.right = m_img_width - 1;
620 m_client_rect.bottom = m_img_height - 1;
621
622 modify_max_val ( );
623 }
624
625 /*------------------------------------------------------------*/
change_max_scan_area(long width,long height)626 void preview_window::change_max_scan_area ( long width, long height )
627 {
628 _pointD pt_scan_size;
629 marquee * marq;
630
631 if ( m_img_width < width || m_img_height < height )
632 return;
633
634 marq = & g_view_manager->get_marquee ();
635
636 pt_scan_size.x = g_view_manager->get_settings ().max_area [ 0 ];
637 pt_scan_size.y = g_view_manager->get_settings ().max_area [ 1 ];
638
639 m_img_rect.left = 0.0;
640 m_img_rect.top = 0.0;
641 m_img_rect.right = pt_scan_size.x * width / m_img_width;
642 m_img_rect.bottom = pt_scan_size.y * height / m_img_height;
643
644 marq->area.x = m_img_rect.right;
645 marq->area.y = m_img_rect.bottom;
646 }
647
648 /*------------------------------------------------------------*/
change_max_disp_area(long width,long height)649 void preview_window::change_max_disp_area ( long width, long height )
650 {
651 long save_prev_x, save_prev_y;
652 long save_img_width, save_img_height;
653 unsigned char * save_img_org;
654 _rectD tmp_rect;
655
656 if ( width < 1 && height < 1 )
657 return;
658
659 if ( g_prev_max_x == width && g_prev_max_y == height )
660 return;
661
662 tmp_rect = m_img_rect;
663
664 if ( m_is_prev == 0 )
665 {
666 g_prev_max_x = width;
667 g_prev_max_y = height;
668
669 get_preview_resolution ( & tmp_rect );
670 resize_preview_window ( 0, 0 );
671
672 clear_image ( );
673
674 return;
675 }
676
677 // save old parameter and image
678 save_prev_x = g_prev_max_x;
679 save_prev_y = g_prev_max_y;
680 save_img_width = m_img_width;
681 save_img_height = m_img_height;
682 save_img_org = new unsigned char [ save_prev_x * save_prev_y * 3 ];
683
684 if ( save_img_org )
685 {
686 ::memcpy ( save_img_org, m_img_org, save_prev_x * save_prev_y * 3 );
687 }
688
689 // resize
690 g_prev_max_x = width;
691 g_prev_max_y = height;
692
693 get_preview_resolution ( & tmp_rect );
694 resize_preview_window ( 0, 0 );
695
696 clear_image ( );
697 m_is_prev = 1;
698
699 // restore image
700 if ( save_img_org )
701 {
702 struct resize_img_info parms;
703
704 parms.in_width = save_img_width;
705 parms.in_height = save_img_height;
706 parms.in_rowbytes = save_prev_x * 3;
707 parms.out_width = m_img_width;
708 parms.out_height = m_img_height;
709 parms.out_rowbytes = g_prev_max_x * 3;
710 parms.bits_per_pixel = 24;
711 parms.resize_flag = PISA_RS_BL;
712 parms.resolution = 0; // just to make sure it's set
713
714 iscan::scale f (parms);
715
716 f.exec (save_img_org, parms.in_height * parms.in_rowbytes,
717 m_img_org, parms.out_height * parms.out_rowbytes);
718
719 delete [] save_img_org;
720 }
721
722 update_img ( );
723 }
724
725 /*------------------------------------------------------------*/
clear_image(void)726 void preview_window::clear_image ( void )
727 {
728 int i;
729
730 m_is_prev = 0;
731
732 ::memset ( m_img, 0xff, m_img_width * 3 );
733 ::memset ( m_img + ( m_img_width * 3 ),
734 0xC4,
735 ( g_prev_max_x - m_img_width ) * 3 );
736
737 for ( i = 0; i < m_img_height; i++ )
738 ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ), m_img,
739 0, i, g_prev_max_x );
740
741 ::memset ( m_img, 0xC4, g_prev_max_x * 3 );
742
743 for ( ; i < g_prev_max_y; i++ )
744 ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ), m_img,
745 0, i, g_prev_max_x );
746
747 ::gtk_widget_draw ( m_prev, 0 );
748 ::gdk_flush ( );
749 }
750
751
752 /*--------------------------------------------------------------*/
draw_marquee(void)753 void preview_window::draw_marquee ( void )
754 {
755 long i, marq_num;
756 _pointL pt_lefttop, pt_rightbottom;
757
758 if ( m_gc == 0 )
759 {
760 m_gc = ::gdk_gc_new ( m_prev->window );
761 ::gdk_gc_set_function ( m_gc, GDK_INVERT );
762 ::gdk_gc_set_line_attributes ( m_gc, 1, GDK_LINE_ON_OFF_DASH,
763 GDK_CAP_BUTT, GDK_JOIN_MITER );
764 }
765
766 marq_num = g_view_manager->get_settings ().get_marquee_size ( );
767
768 if ( marq_num < 2 || m_on_preview )
769 return;
770
771 for ( i = 1; i < marq_num; i++ )
772 {
773 get_marquee_point ( i, & pt_lefttop, & pt_rightbottom );
774
775 draw_rect ( pt_lefttop, pt_rightbottom );
776 }
777 }
778
779 /*--------------------------------------------------------------*/
reset_settings(pisa_preview_type type)780 void preview_window::reset_settings ( pisa_preview_type type )
781 {
782 long i, n, m, marq_num;
783 marquee * marq;
784 gamma_correction * gamma_cls;
785 scan_manager * scan_mgr;
786
787 gamma_cls = ( gamma_correction * ) ::g_view_manager->get_window_cls ( ID_WINDOW_GAMMA );
788
789 scan_mgr = g_view_manager->get_scan_manager ();
790 marq_num = g_view_manager->get_marquee_size ();
791
792 if ( type == PISA_PREV_WHOLE )
793 {
794 while ( 1 < marq_num )
795 {
796 g_view_manager->del_marquee (marq_num - 1);
797 marq_num = g_view_manager->get_marquee_size ();
798 }
799
800 gamma_cls->reset ( 1 );
801 }
802
803 marq_num = g_view_manager->get_marquee_size ();
804
805 for ( i = 0; i < marq_num; i++ )
806 {
807 marq = & g_view_manager->get_marquee (i);
808
809 if ( type == PISA_PREV_WHOLE )
810 {
811 marq->gamma = ( long ) ( 100 * DEFGAMMA );
812 marq->highlight = DEFHIGHLIGHT;
813 marq->shadow = DEFSHADOW;
814 marq->threshold = DEFTHRESHOLD;
815
816 for ( n = 0; n < 4; n++ )
817 for ( m = 0; m < 256; m++ )
818 marq->gamma_table [ n ] [ m ] = m;
819
820 marq->graybalance = DEFGRAYBALANCE;
821 marq->saturation = DEFSATURATION;
822 }
823
824 for ( n = 0; n < 3; n++ )
825 {
826 marq->film_gamma [ n ] = 1.0;
827 marq->film_yp [ n ] = 0.0;
828 marq->grayl [ n ] = 0.0;
829 }
830
831 iscan::build_LUT (const_cast <settings *> (&g_view_manager
832 ->get_settings ()),
833 marq, scan_mgr->is_dumb ());
834 }
835 }
836
837 int
set_preview_param(pisa_preview_type type)838 preview_window::set_preview_param (pisa_preview_type type)
839 {
840 settings set = g_view_manager->get_settings ();
841 marquee marq;
842
843 if (PISA_PREV_WHOLE == type)
844 {
845 marq.offset.x = 0.0;
846 marq.offset.y = 0.0;
847 marq.area.x = set.max_area[0];
848 marq.area.y = set.max_area[1];
849 }
850 else
851 {
852 float rate = 0.1f;
853 _pointD pt_offset, pt_area, pt_max;
854
855 marquee cur_marq = g_view_manager->get_marquee ();
856
857 marq.focus = cur_marq.focus;
858
859 pt_offset = cur_marq.offset;
860 pt_area = cur_marq.area;
861
862 marquee whole_marq = g_view_manager->get_marquee (0);
863
864 pt_max.x = whole_marq.area.x;
865 pt_max.y = whole_marq.area.y;
866
867 zoom_boundary (pt_offset, pt_area, pt_max, rate);
868
869 marq.offset.x = pt_offset.x;
870 marq.offset.y = pt_offset.y;
871 marq.area.x = pt_area.x;
872 marq.area.y = pt_area.y;
873 }
874
875 _rectD img_rect;
876 img_rect.left = marq.offset.x;
877 img_rect.top = marq.offset.y;
878 img_rect.right = marq.offset.x + marq.area.x;
879 img_rect.bottom = marq.offset.y + marq.area.y;
880
881 long resolution = get_preview_resolution (&img_rect);
882
883 pisa_error_id err = (g_view_manager->get_scan_manager ()
884 ->set_scan_parameters (set, marq, type, resolution));
885
886 return err;
887 }
888
889 /*------------------------------------------------------------*/
tool_usm(const pisa_image_info & info)890 void preview_window::tool_usm (const pisa_image_info& info)
891 {
892 iscan::focus f (info);
893
894 f.exec (info.m_img, info.m_height * info.m_rowbytes,
895 info.m_img, info.m_height * info.m_rowbytes);
896 }
897
898 void
zoom_boundary(_pointD & pt_offset,_pointD & pt_area,const _pointD & pt_max,float rate) const899 preview_window::zoom_boundary (_pointD& pt_offset, _pointD& pt_area,
900 const _pointD& pt_max, float rate) const
901 {
902 _pointD pt_result_offset, pt_result_area;
903 double bound_size;
904
905 if (pt_area.x < pt_area.y)
906 bound_size = pt_area.y * rate;
907 else
908 bound_size = pt_area.x * rate;
909
910 bound_size = (0.0 == bound_size) ? 0.01 : bound_size;
911
912 // left
913 pt_result_offset.x = pt_offset.x - bound_size;
914 if (0.0 > pt_result_offset.x)
915 pt_result_offset.x = 0.0;
916
917 // top
918 pt_result_offset.y = pt_offset.y - bound_size;
919 if (0.0 > pt_result_offset.y)
920 pt_result_offset.y = 0.0;
921
922 // right
923 pt_result_area.x = ((pt_offset.x - pt_result_offset.x) +
924 pt_area.x + bound_size);
925 if (pt_max.x < pt_result_offset.x + pt_result_area.x)
926 pt_result_area.x = pt_max.x - pt_result_offset.x;
927
928 // bottom
929 pt_result_area.y = ((pt_offset.y - pt_result_offset.y) +
930 pt_area.y + bound_size);
931 if (pt_max.y < pt_result_offset.y + pt_result_area.y)
932 pt_result_area.y = pt_max.y - pt_result_offset.y;
933
934 pt_offset = pt_result_offset;
935 pt_area = pt_result_area;
936 }
937
938 /*--------------------------------------------------------------*/
create_cursor(void)939 void preview_window::create_cursor ( void )
940 {
941 m_cursor [ PISA_CS_ARROW ] = ::gdk_cursor_new ( GDK_ARROW );
942 m_cursor [ PISA_CS_HAND ] = ::gdk_cursor_new ( GDK_HAND2 );
943 m_cursor [ PISA_CS_CROSS ] = ::gdk_cursor_new ( GDK_CROSS );
944 m_cursor [ PISA_CS_TOP ] = ::gdk_cursor_new ( GDK_TOP_SIDE );
945 m_cursor [ PISA_CS_BOTTOM ] = ::gdk_cursor_new ( GDK_BOTTOM_SIDE );
946 m_cursor [ PISA_CS_LEFT ] = ::gdk_cursor_new ( GDK_LEFT_SIDE );
947 m_cursor [ PISA_CS_RIGHT ] = ::gdk_cursor_new ( GDK_RIGHT_SIDE );
948 m_cursor [ PISA_CS_LEFTTOP ] = ::gdk_cursor_new ( GDK_TOP_LEFT_CORNER );
949 m_cursor [ PISA_CS_LEFTBOTTOM ] = ::gdk_cursor_new ( GDK_BOTTOM_LEFT_CORNER );
950 m_cursor [ PISA_CS_RIGHTTOP ] = ::gdk_cursor_new ( GDK_TOP_RIGHT_CORNER );
951 m_cursor [ PISA_CS_RIGHTBOTTOM ] = ::gdk_cursor_new ( GDK_BOTTOM_RIGHT_CORNER );
952 }
953
954
955 /*--------------------------------------------------------------*/
set_mouse_cursor(int x,int y)956 int preview_window::set_mouse_cursor ( int x, int y )
957 {
958 const long ADDSIZE = 3;
959 long marq_num;
960 _pointL pt_lefttop, pt_rightbottom;
961 int cursor_state;
962 _pointL pt;
963 int pt_in_cur_marq;
964 _rectL judge_rect;
965 _pointL pt_lt, pt_rb;
966 int i;
967
968 if ( m_drag == 1 )
969 return FALSE;
970
971 pt.x = x;
972 pt.y = y;
973
974 if ( 0 == ::pt_in_rect ( m_client_rect, pt ) )
975 {
976 m_cursor_state = PISA_CS_ARROW;
977 return FALSE;
978 }
979
980 marq_num = g_view_manager->get_settings ().get_marquee_size ( );
981
982 if ( marq_num < 2 )
983 {
984 m_cursor_state = PISA_CS_CROSS;
985 return FALSE;
986 }
987
988 get_marquee_point ( marq_num - 1, & pt_lefttop, & pt_rightbottom );
989
990 cursor_state = search_cursor_state ( pt_lefttop, pt_rightbottom, pt );
991 if ( cursor_state != PISA_CS_CROSS )
992 {
993 m_cursor_state = cursor_state;
994 return FALSE;
995 }
996
997 judge_rect.left = pt_lefttop.x;
998 judge_rect.right = pt_rightbottom.x;
999 judge_rect.top = pt_lefttop.y;
1000 judge_rect.bottom = pt_rightbottom.y;
1001 if ( pt_in_rect ( judge_rect, pt ) )
1002 pt_in_cur_marq = 1;
1003 else
1004 pt_in_cur_marq = 0;
1005
1006 for ( i = marq_num - 1; 0 < i; i-- )
1007 {
1008 if ( marq_num - 1 == i )
1009 continue;
1010
1011 get_marquee_point ( i, & pt_lt, & pt_rb );
1012
1013 if ( pt_in_cur_marq )
1014 {
1015 cursor_state = search_cursor_state ( pt_lt, pt_rb, pt );
1016 if ( PISA_CS_CROSS != cursor_state )
1017 {
1018 m_cursor_state = PISA_CS_ARROW;
1019 return i;
1020 }
1021 }
1022 else
1023 {
1024 judge_rect.left = pt_lt.x - ADDSIZE;
1025 judge_rect.right = pt_rb.x + ADDSIZE;
1026 judge_rect.top = pt_lt.y - ADDSIZE;
1027 judge_rect.bottom = pt_rb.y + ADDSIZE;
1028 if ( pt_in_rect ( judge_rect, pt ) )
1029 {
1030 m_cursor_state = PISA_CS_ARROW;
1031 return i;
1032 }
1033 }
1034 }
1035
1036 if ( pt_in_cur_marq )
1037 {
1038 m_cursor_state = PISA_CS_HAND;
1039 return 0;
1040 }
1041
1042 m_cursor_state = PISA_CS_CROSS;
1043
1044 return 0;
1045 }
1046
1047 /*--------------------------------------------------------------*/
search_cursor_state(const _pointL & pt_lt,const _pointL & pt_rb,const _pointL & pt)1048 int preview_window::search_cursor_state ( const _pointL & pt_lt,
1049 const _pointL & pt_rb,
1050 const _pointL & pt )
1051 {
1052 const long ADDSIZE = 3;
1053 _rectL judge_rect;
1054
1055 // check left top
1056 judge_rect.left = pt_lt.x - ADDSIZE;
1057 judge_rect.right = pt_lt.x + ADDSIZE;
1058 judge_rect.top = pt_lt.y - ADDSIZE;
1059 judge_rect.bottom = pt_lt.y + ADDSIZE;
1060 if ( ::pt_in_rect ( judge_rect, pt ) )
1061 return PISA_CS_LEFTTOP;
1062
1063 // check right bottom
1064 judge_rect.left = pt_rb.x - ADDSIZE;
1065 judge_rect.right = pt_rb.x + ADDSIZE;
1066 judge_rect.top = pt_rb.y - ADDSIZE;
1067 judge_rect.bottom = pt_rb.y + ADDSIZE;
1068 if ( ::pt_in_rect ( judge_rect, pt ) )
1069 return PISA_CS_RIGHTBOTTOM;
1070
1071 // check right top
1072 judge_rect.left = pt_rb.x - ADDSIZE;
1073 judge_rect.right = pt_rb.x + ADDSIZE;
1074 judge_rect.top = pt_lt.y - ADDSIZE;
1075 judge_rect.bottom = pt_lt.y + ADDSIZE;
1076 if ( ::pt_in_rect ( judge_rect, pt ) )
1077 return PISA_CS_RIGHTTOP;
1078
1079 // check left bottom
1080 judge_rect.left = pt_lt.x - ADDSIZE;
1081 judge_rect.right = pt_lt.x + ADDSIZE;
1082 judge_rect.top = pt_rb.y - ADDSIZE;
1083 judge_rect.bottom = pt_rb.y + ADDSIZE;
1084 if ( ::pt_in_rect ( judge_rect, pt ) )
1085 return PISA_CS_LEFTBOTTOM;
1086
1087 // check left resizing
1088 judge_rect.left = pt_lt.x - ADDSIZE;
1089 judge_rect.right = pt_lt.x + ADDSIZE;
1090 judge_rect.top = pt_lt.y;
1091 judge_rect.bottom = pt_rb.y;
1092 if ( ::pt_in_rect ( judge_rect, pt ) )
1093 return PISA_CS_LEFT;
1094
1095 // check right resizing
1096 judge_rect.left = pt_rb.x - ADDSIZE;
1097 judge_rect.right = pt_rb.x + ADDSIZE;
1098 judge_rect.top = pt_lt.y;
1099 judge_rect.bottom = pt_rb.y;
1100 if ( ::pt_in_rect ( judge_rect, pt ) )
1101 return PISA_CS_RIGHT;
1102
1103 // check top resizing
1104 judge_rect.left = pt_lt.x;
1105 judge_rect.right = pt_rb.x;
1106 judge_rect.top = pt_lt.y - ADDSIZE;
1107 judge_rect.bottom = pt_lt.y + ADDSIZE;
1108 if ( ::pt_in_rect ( judge_rect, pt ) )
1109 return PISA_CS_TOP;
1110
1111 // check bottom resizing
1112 judge_rect.left = pt_lt.x;
1113 judge_rect.right = pt_rb.x;
1114 judge_rect.top = pt_rb.y - ADDSIZE;
1115 judge_rect.bottom = pt_rb.y + ADDSIZE;
1116 if ( ::pt_in_rect ( judge_rect, pt ) )
1117 return PISA_CS_BOTTOM;
1118
1119 return PISA_CS_CROSS;
1120 }
1121
1122 /*--------------------------------------------------------------*/
change_cursor(void)1123 void preview_window::change_cursor ( void )
1124 {
1125 ::gdk_window_set_cursor ( m_prev->window,
1126 m_cursor [ m_cursor_state ] );
1127 }
1128
1129 /*--------------------------------------------------------------*/
modify_max_val(void)1130 void preview_window::modify_max_val ( void )
1131 {
1132 marquee * whole_marq;
1133 _pointD pt_min_D, pt_max_D;
1134
1135 whole_marq = & g_view_manager->get_marquee (0);
1136 m_max_img_rect.top = 0.0;
1137 m_max_img_rect.left = 0.0;
1138 m_max_img_rect.right = whole_marq->area.x;
1139 m_max_img_rect.bottom = whole_marq->area.y;
1140
1141 pt_min_D.x = m_max_img_rect.left;
1142 pt_min_D.y = m_max_img_rect.top;
1143 pt_max_D.x = m_max_img_rect.right;
1144 pt_max_D.y = m_max_img_rect.bottom;
1145 m_pt_max_rb = inches2clientpix ( pt_max_D );
1146 m_pt_max_lt.x = 0;
1147 m_pt_max_lt.y = 0;
1148 m_pt_max_rb.x = m_img_width - 1;
1149 m_pt_max_rb.y = m_img_height - 1;
1150 }
1151
1152 /*--------------------------------------------------------------*/
mouse_down(GdkEvent * event)1153 gint preview_window::mouse_down ( GdkEvent * event )
1154 {
1155 marquee * cur_marq;
1156 _pointL pt_lefttop, pt_rightbottom;
1157 long id_cur_marquee;
1158
1159 if ( event->button.button != 1 )
1160 return TRUE;
1161
1162 if ( m_img_width - 1 < ( int ) event->button.x || m_img_height - 1 < ( int ) event->button.y )
1163 return TRUE;
1164
1165 m_pt_begin.x = ( int ) event->button.x;
1166 m_pt_begin.y = ( int ) event->button.y;
1167
1168 m_drag = 1;
1169
1170 m_pt_old = m_pt_begin;
1171
1172 id_cur_marquee = g_view_manager->get_marquee_size () - 1;
1173 get_marquee_point ( id_cur_marquee, & pt_lefttop, & pt_rightbottom );
1174
1175 cur_marq = & g_view_manager->get_marquee ();
1176
1177 m_pt_save_offset = cur_marq->offset;
1178 m_pt_save_area = cur_marq->area;
1179
1180 switch ( m_cursor_state )
1181 {
1182 case PISA_CS_CROSS:
1183 m_pt_old_lt = m_pt_old_rb = m_pt_begin;
1184 delete_marquee ( );
1185 create_marquee ( m_pt_old_lt, m_pt_old_rb );
1186 break;
1187 case PISA_CS_HAND:
1188 case PISA_CS_TOP:
1189 case PISA_CS_BOTTOM:
1190 case PISA_CS_LEFT:
1191 case PISA_CS_RIGHT:
1192 case PISA_CS_LEFTTOP:
1193 case PISA_CS_LEFTBOTTOM:
1194 case PISA_CS_RIGHTTOP:
1195 case PISA_CS_RIGHTBOTTOM:
1196 m_pt_old_lt = pt_lefttop;
1197 m_pt_old_rb = pt_rightbottom;
1198 break;
1199 }
1200
1201 return FALSE;
1202 }
1203
1204 /*--------------------------------------------------------------*/
mouse_move(GdkEvent * event)1205 gint preview_window::mouse_move ( GdkEvent * event )
1206 {
1207 int x, y;
1208 GdkModifierType state;
1209 _pointL pt_mouse, pt_move, pt_tmp_lt, pt_tmp_rb, pt_min_L;
1210 _pointD pt_lefttop, pt_rightbottom, pt_min_D, pt_zero_D;
1211
1212 if ( event->motion.is_hint )
1213 {
1214 ::gdk_window_get_pointer ( m_prev->window, & x, & y, & state );
1215 }
1216 else
1217 return TRUE;
1218
1219 if ( m_drag == 0 )
1220 {
1221 set_mouse_cursor ( x, y );
1222 change_cursor ( );
1223 return FALSE;
1224 }
1225
1226 if ( x < 0 ) x = 0;
1227 if ( y < 0 ) y = 0;
1228 if ( m_client_rect.right < x ) x = m_client_rect.right;
1229 if ( m_client_rect.bottom < y ) y = m_client_rect.bottom;
1230
1231 pt_mouse.x = x;
1232 pt_mouse.y = y;
1233
1234 // clear previous marquee
1235 draw_rect ( m_pt_old_lt, m_pt_old_rb );
1236
1237 pt_lefttop = m_pt_save_offset;
1238 pt_rightbottom = m_pt_save_offset + m_pt_save_area;
1239
1240 pt_tmp_lt = inches2clientpix ( pt_lefttop );
1241 pt_tmp_rb = inches2clientpix ( pt_rightbottom );
1242
1243 pt_zero_D.x = 0.0;
1244 pt_zero_D.y = 0.0;
1245 pt_min_D.x = g_min_marq_size;
1246 pt_min_D.y = g_min_marq_size;
1247 pt_min_L = inches2clientpix ( pt_min_D ) - inches2clientpix ( pt_zero_D );
1248
1249 pt_move = pt_mouse - m_pt_begin;
1250
1251 // initialize
1252 begin_mouse_move ( & pt_tmp_lt, & pt_tmp_rb );
1253
1254 move_rect ( & pt_tmp_lt, & pt_tmp_rb, pt_move );
1255
1256 switch ( m_cursor_state )
1257 {
1258 case PISA_CS_CROSS:
1259 m_pt_old_rb = pt_mouse;
1260 break;
1261 case PISA_CS_HAND:
1262 m_pt_old_rb = pt_tmp_lt + ( m_pt_old_rb - m_pt_old_lt );
1263 m_pt_old_lt = pt_tmp_lt;
1264 break;
1265 case PISA_CS_TOP:
1266 if ( m_pt_old_rb.y - pt_min_L.y > pt_tmp_lt.y )
1267 m_pt_old_lt.y = pt_tmp_lt.y;
1268 else
1269 m_pt_old_lt.y = m_pt_old_rb.y - pt_min_L.y;
1270 break;
1271 case PISA_CS_BOTTOM:
1272 if ( m_pt_old_lt.y + pt_min_L.y < pt_tmp_rb.y )
1273 m_pt_old_rb.y = pt_tmp_rb.y;
1274 else
1275 m_pt_old_rb.y = m_pt_old_lt.y + pt_min_L.y;
1276 break;
1277 case PISA_CS_LEFT:
1278 if ( m_pt_old_rb.x - pt_min_L.x > pt_tmp_lt.x )
1279 m_pt_old_lt.x = pt_tmp_lt.x;
1280 else
1281 m_pt_old_lt.x = m_pt_old_rb.x - pt_min_L.x;
1282 break;
1283 case PISA_CS_RIGHT:
1284 if ( m_pt_old_lt.x + pt_min_L.x < pt_tmp_rb.x )
1285 m_pt_old_rb.x = pt_tmp_rb.x;
1286 else
1287 m_pt_old_rb.x = m_pt_old_lt.x + pt_min_L.x;
1288 break;
1289 case PISA_CS_LEFTTOP:
1290 if ( m_pt_old_rb.y - pt_min_L.y > pt_tmp_lt.y )
1291 m_pt_old_lt.y = pt_tmp_lt.y;
1292 else
1293 m_pt_old_lt.y = m_pt_old_rb.y - pt_min_L.y;
1294 if ( m_pt_old_rb.x - pt_min_L.x > pt_tmp_lt.x )
1295 m_pt_old_lt.x = pt_tmp_lt.x;
1296 else
1297 m_pt_old_lt.x = m_pt_old_rb.x - pt_min_L.x;
1298 break;
1299 case PISA_CS_LEFTBOTTOM:
1300 if ( m_pt_old_rb.x - pt_min_L.x > pt_tmp_lt.x )
1301 m_pt_old_lt.x = pt_tmp_lt.x;
1302 else
1303 m_pt_old_lt.x = m_pt_old_rb.x - pt_min_L.x;
1304 if ( m_pt_old_lt.y + pt_min_L.y < pt_tmp_rb.y )
1305 m_pt_old_rb.y = pt_tmp_rb.y;
1306 else
1307 m_pt_old_rb.y = m_pt_old_lt.y + pt_min_L.y;
1308 break;
1309 case PISA_CS_RIGHTTOP:
1310 if ( m_pt_old_rb.y - pt_min_L.y > pt_tmp_lt.y )
1311 m_pt_old_lt.y = pt_tmp_lt.y;
1312 else
1313 m_pt_old_lt.y = m_pt_old_rb.y - pt_min_L.y;
1314 if ( m_pt_old_lt.x + pt_min_L.x < pt_tmp_rb.x )
1315 m_pt_old_rb.x = pt_tmp_rb.x;
1316 else
1317 m_pt_old_rb.x = m_pt_old_lt.x + pt_min_L.x;
1318 break;
1319 case PISA_CS_RIGHTBOTTOM:
1320 if ( m_pt_old_lt.y + pt_min_L.y < pt_tmp_rb.y )
1321 m_pt_old_rb.y = pt_tmp_rb.y;
1322 else
1323 m_pt_old_rb.y = m_pt_old_lt.y + pt_min_L.y;
1324 if ( m_pt_old_lt.x + pt_min_L.x < pt_tmp_rb.x )
1325 m_pt_old_rb.x = pt_tmp_rb.x;
1326 else
1327 m_pt_old_rb.x = m_pt_old_lt.x + pt_min_L.x;
1328 break;
1329 }
1330
1331 draw_rect ( m_pt_old_lt, m_pt_old_rb );
1332
1333 if ( m_cursor_state != PISA_CS_HAND )
1334 resize_marquee ( m_pt_old_lt, m_pt_old_rb );
1335
1336 m_pt_old = pt_mouse;
1337
1338 return FALSE;
1339 }
1340
1341 /*--------------------------------------------------------------*/
mouse_up(GdkEvent * event)1342 gint preview_window::mouse_up ( GdkEvent * event )
1343 {
1344 int min_check, move;
1345 _pointL pt_mouse;
1346 long marq_num;
1347
1348 if ( 0 == m_drag )
1349 return FALSE;
1350
1351 pt_mouse.x = ( int ) event->button.x;
1352 pt_mouse.y = ( int ) event->button.y;
1353
1354 move = ( m_pt_begin.x != pt_mouse.x ) || ( m_pt_begin.y != pt_mouse.y );
1355
1356 // clear previous marquee
1357 marq_num = g_view_manager->get_marquee_size ();
1358 if ( 1 < marq_num )
1359 draw_rect ( m_pt_old_lt, m_pt_old_rb );
1360
1361 switch ( m_cursor_state )
1362 {
1363 case PISA_CS_CROSS:
1364 min_check = check_min_size ( m_pt_old_lt, m_pt_old_rb );
1365 if ( min_check == 0 )
1366 delete_marquee ( );
1367 update_img ( );
1368 break;
1369 case PISA_CS_ARROW:
1370 break;
1371 case PISA_CS_HAND:
1372 move_marquee ( m_pt_old_lt, m_pt_old_rb );
1373 update_img ( );
1374 break;
1375 case PISA_CS_LEFT:
1376 case PISA_CS_LEFTTOP:
1377 case PISA_CS_LEFTBOTTOM:
1378 case PISA_CS_RIGHT:
1379 case PISA_CS_RIGHTTOP:
1380 case PISA_CS_RIGHTBOTTOM:
1381 case PISA_CS_TOP:
1382 case PISA_CS_BOTTOM:
1383 if ( 0 == check_min_size ( m_pt_old_lt, m_pt_old_rb ) )
1384 delete_marquee ( );
1385 update_img ( PISA_CS_LEFT == m_cursor_state
1386 || PISA_CS_LEFTTOP == m_cursor_state
1387 || PISA_CS_LEFTBOTTOM == m_cursor_state);
1388 break;
1389 }
1390
1391 m_drag = 0;
1392
1393 set_mouse_cursor ( pt_mouse.x, pt_mouse.y );
1394 change_cursor ( );
1395
1396 return FALSE;
1397 }
1398
1399 /*--------------------------------------------------------------*/
create_marquee(const _pointL & pt_lt,const _pointL & pt_rb)1400 int preview_window::create_marquee ( const _pointL & pt_lt, const _pointL & pt_rb )
1401 {
1402 _pointL pt_lefttop_L, pt_rightbottom_L;
1403 _pointD pt_lefttop_D, pt_rightbottom_D, pt_area_D;
1404 marquee * new_marq, * whole_marq;
1405
1406 pt_lefttop_L = pt_lt;
1407 pt_rightbottom_L = pt_rb;
1408 check_ltrb ( & pt_lefttop_L, & pt_rightbottom_L );
1409
1410 pt_lefttop_D = clientpix2inches ( pt_lefttop_L );
1411 pt_rightbottom_D = clientpix2inches ( pt_rightbottom_L );
1412 pt_area_D = pt_rightbottom_D - pt_lefttop_D;
1413
1414 check_max_size ( & pt_lefttop_D, & pt_area_D, 0 );
1415
1416 whole_marq = & g_view_manager->get_marquee (0);
1417 new_marq = new marquee;
1418 * new_marq = * whole_marq;
1419
1420 new_marq->offset = pt_lefttop_D;
1421 new_marq->area = pt_area_D;
1422
1423 g_view_manager->add_marquee (&new_marq);
1424
1425 ::g_view_manager->sensitive ( );
1426
1427 return 1;
1428 }
1429
1430 /*--------------------------------------------------------------*/
delete_marquee(void)1431 int preview_window::delete_marquee ( void )
1432 {
1433 long num_marq;
1434 int i, j;
1435 marquee * cur_marq, * whole_marq;
1436
1437 num_marq = g_view_manager->get_marquee_size ();
1438
1439 // no marquee
1440 if ( num_marq < 2 )
1441 return PISA_ERR_SUCCESS;
1442
1443 whole_marq = & g_view_manager->get_marquee (0);
1444 cur_marq = & g_view_manager->get_marquee ();
1445
1446 whole_marq->gamma = cur_marq->gamma;
1447 whole_marq->highlight = cur_marq->highlight;
1448 whole_marq->shadow = cur_marq->shadow;
1449 whole_marq->threshold = cur_marq->threshold;
1450
1451 for ( i = 0; i < 4; i++ )
1452 for ( j = 0; j < 256; j++ )
1453 whole_marq->gamma_table [ i ] [ j ] = cur_marq->gamma_table [ i ] [ j ];
1454
1455 whole_marq->graybalance = cur_marq->graybalance;
1456 whole_marq->saturation = cur_marq->saturation;
1457
1458 whole_marq->scale = cur_marq->scale;
1459
1460 whole_marq->focus = cur_marq->focus;
1461
1462 for ( i = 0; i < 3; i++ )
1463 {
1464 whole_marq->film_gamma [ i ] = cur_marq->film_gamma [ i ];
1465 whole_marq->film_yp [ i ] = cur_marq->film_yp [ i ];
1466 whole_marq->grayl [ i ] = cur_marq->grayl [ i ];
1467 }
1468
1469 for ( i = 0; i < 256; i++ )
1470 {
1471 whole_marq->lut.gamma_r [ i ] = cur_marq->lut.gamma_r [ i ];
1472 whole_marq->lut.gamma_g [ i ] = cur_marq->lut.gamma_g [ i ];
1473 whole_marq->lut.gamma_b [ i ] = cur_marq->lut.gamma_b [ i ];
1474 }
1475
1476 g_view_manager->del_marquee ();
1477
1478 ::g_view_manager->sensitive ( );
1479 update_img ( );
1480
1481 return PISA_ERR_SUCCESS;
1482 }
1483
1484 /*--------------------------------------------------------------*/
move_marquee(const _pointL & pt_lt,const _pointL & pt_rb)1485 void preview_window::move_marquee ( const _pointL & pt_lt,
1486 const _pointL & pt_rb )
1487 {
1488 _pointL pt_lefttop_L, pt_rightbottom_L, pt_tmp;
1489 _pointD pt_lefttop_D, pt_rightbottom_D, pt_offset, pt_area;
1490 marquee * cur_marq;
1491
1492 pt_tmp = pt_rb;
1493
1494 pt_lefttop_L = pt_lt;
1495 pt_lefttop_D = clientpix2inches ( pt_lefttop_L );
1496 pt_rightbottom_D = clientpix2inches ( pt_rightbottom_L );
1497
1498 pt_offset = pt_lefttop_D;
1499 pt_area = pt_rightbottom_D - pt_lefttop_D;
1500
1501 check_max_size ( & pt_offset, & pt_area, 1 );
1502
1503 cur_marq = & g_view_manager->get_marquee ();
1504
1505 cur_marq->offset = pt_offset;
1506
1507 ::g_view_manager->sensitive ( );
1508 }
1509
1510 /*--------------------------------------------------------------*/
resize_marquee(const _pointL & pt_lt,const _pointL & pt_rb)1511 void preview_window::resize_marquee ( const _pointL & pt_lt,
1512 const _pointL & pt_rb )
1513 {
1514 _pointL pt_lefttop_L, pt_rightbottom_L;
1515 _pointD pt_lefttop_D, pt_rightbottom_D, pt_offset, pt_area;
1516 marquee * cur_marq;
1517
1518 pt_lefttop_L = pt_lt;
1519 pt_rightbottom_L = pt_rb;
1520
1521 check_ltrb ( & pt_lefttop_L, & pt_rightbottom_L );
1522
1523 pt_lefttop_D = clientpix2inches ( pt_lefttop_L );
1524 pt_rightbottom_D = clientpix2inches ( pt_rightbottom_L );
1525
1526 pt_offset = pt_lefttop_D;
1527 pt_area = pt_rightbottom_D - pt_lefttop_D;
1528
1529 check_max_size ( & pt_offset, & pt_area, 0 );
1530
1531 cur_marq = & g_view_manager->get_marquee ();
1532
1533 cur_marq->offset = pt_offset;
1534 cur_marq->area = pt_area;
1535
1536 ::g_view_manager->sensitive ( );
1537 }
1538
1539 /*--------------------------------------------------------------*/
begin_mouse_move(_pointL * pt_lt,_pointL * pt_rb)1540 void preview_window::begin_mouse_move ( _pointL * pt_lt, _pointL * pt_rb )
1541 {
1542 switch ( m_cursor_state )
1543 {
1544 case PISA_CS_CROSS:
1545 case PISA_CS_HAND:
1546 break;
1547 case PISA_CS_TOP:
1548 pt_lt->x = pt_rb->x;
1549 pt_rb->y = pt_lt->y;
1550 break;
1551 case PISA_CS_BOTTOM:
1552 * pt_lt = * pt_rb;
1553 break;
1554 case PISA_CS_LEFT:
1555 pt_lt->y = pt_rb->y;
1556 pt_rb->x = pt_lt->x;
1557 break;
1558 case PISA_CS_RIGHT:
1559 * pt_lt = * pt_rb;
1560 break;
1561 case PISA_CS_LEFTTOP:
1562 * pt_rb = * pt_lt;
1563 break;
1564 case PISA_CS_LEFTBOTTOM:
1565 pt_lt->y = pt_rb->y;
1566 pt_rb->x = pt_lt->x;
1567 break;
1568 case PISA_CS_RIGHTBOTTOM:
1569 * pt_lt = * pt_rb;
1570 break;
1571 case PISA_CS_RIGHTTOP:
1572 pt_lt->x = pt_rb->x;
1573 pt_rb->y = pt_lt->y;
1574 break;
1575 }
1576 }
1577
1578 /*--------------------------------------------------------------*/
move_rect(_pointL * pt_lt,_pointL * pt_rb,const _pointL & pt_move)1579 void preview_window::move_rect ( _pointL * pt_lt, _pointL * pt_rb,
1580 const _pointL & pt_move )
1581 {
1582 // move direction
1583 typedef enum { DIR_LT, DIR_LB, DIR_RT, DIR_RB } MOVE_DIR;
1584 MOVE_DIR direction;
1585 _pointL pt_tmp, pt_tmp_move ( pt_move );
1586 _pointL pt_size;
1587 _pointD pt_lefttop_D, pt_rightbottom_D;
1588 _pointL pt_lefttop_L, pt_rightbottom_L;
1589
1590 if ( pt_move.x < 0 )
1591 {
1592 if ( pt_move.y < 0 )
1593 direction = DIR_LT;
1594 else
1595 direction = DIR_LB;
1596 }
1597 else
1598 {
1599 if ( pt_move.y < 0 )
1600 direction = DIR_RT;
1601 else
1602 direction = DIR_RB;
1603 }
1604
1605 pt_lefttop_D = m_pt_save_offset;
1606 pt_rightbottom_D = m_pt_save_offset + m_pt_save_area;
1607
1608 pt_lefttop_L = inches2clientpix ( pt_lefttop_D );
1609 pt_rightbottom_L = inches2clientpix ( pt_rightbottom_D );
1610
1611 pt_size.x = pt_rightbottom_L.x - pt_lefttop_L.x + 1;
1612 pt_size.y = pt_rightbottom_L.y - pt_lefttop_L.y + 1;
1613
1614 switch ( direction )
1615 {
1616 case DIR_LT:
1617 pt_tmp.x = pt_lt->x + pt_tmp_move.x;
1618 if ( pt_tmp.x < m_pt_max_lt.x )
1619 pt_tmp.x = m_pt_max_lt.x;
1620 pt_tmp.y = pt_lt->y + pt_tmp_move.y;
1621 if ( pt_tmp.y < m_pt_max_lt.y )
1622 pt_tmp.y = m_pt_max_lt.y;
1623 * pt_rb = pt_tmp + ( * pt_rb - * pt_lt );
1624 * pt_lt = pt_tmp;
1625 break;
1626 case DIR_LB:
1627 pt_tmp.x = pt_lt->x + pt_tmp_move.x;
1628 if ( pt_tmp.x < m_pt_max_lt.x )
1629 pt_tmp.x = m_pt_max_lt.x;
1630 pt_tmp.y = pt_rb->y + pt_tmp_move.y;
1631 if ( m_pt_max_rb.y < pt_tmp.y )
1632 pt_tmp.y = m_pt_max_rb.y;
1633 pt_lt->y = pt_tmp.y - ( pt_rb->y - pt_lt->y );
1634 pt_rb->x = pt_tmp.x - ( pt_rb->x - pt_lt->x );
1635 pt_lt->x = pt_tmp.x;
1636 pt_rb->y = pt_tmp.y;
1637 break;
1638 case DIR_RT:
1639 pt_tmp.x = pt_rb->x + pt_tmp_move.x;
1640 if ( m_pt_max_rb.x < pt_tmp.x )
1641 pt_tmp.x = m_pt_max_rb.x;
1642 pt_tmp.y = pt_lt->y + pt_tmp_move.y;
1643 if ( pt_tmp.y < m_pt_max_lt.y )
1644 pt_tmp.y = m_pt_max_lt.y;
1645 pt_lt->x = pt_tmp.x - ( pt_rb->x - pt_lt->x );
1646 pt_rb->y = pt_tmp.y + ( pt_rb->y - pt_lt->y );
1647 pt_lt->y = pt_tmp.y;
1648 pt_rb->x = pt_tmp.x;
1649 break;
1650 case DIR_RB:
1651 pt_tmp.x = pt_rb->x + pt_tmp_move.x;
1652 if ( m_pt_max_rb.x < pt_tmp.x )
1653 pt_tmp.x = m_pt_max_rb.x;
1654 pt_tmp.y = pt_rb->y + pt_tmp_move.y;
1655 if ( m_pt_max_rb.y < pt_tmp.y )
1656 pt_tmp.y = m_pt_max_rb.y;
1657 * pt_lt = pt_tmp - ( * pt_rb - * pt_lt );
1658 * pt_rb = pt_tmp;
1659 break;
1660 }
1661 }
1662
1663 /*--------------------------------------------------------------*/
clientpix2inches(_pointL & pt)1664 _pointD preview_window::clientpix2inches ( _pointL & pt )
1665 {
1666 _pointD pt_result;
1667 _pointD pt_tmp;
1668 double da, db;
1669
1670 da = m_client_rect.right - m_client_rect.left;
1671 db = m_img_rect.right - m_img_rect.left;
1672 pt_tmp.x = similarity ( ( double ) pt.x, da, db );
1673
1674 da = m_client_rect.bottom - m_client_rect.top;
1675 db = m_img_rect.bottom - m_img_rect.top;
1676 pt_tmp.y = similarity ( ( double ) pt.y, da, db );
1677
1678
1679 pt_result.x = m_img_rect.left + pt_tmp.x;
1680 pt_result.y = m_img_rect.top + pt_tmp.y;
1681
1682 return pt_result;
1683 }
1684
1685 /*--------------------------------------------------------------*/
inches2clientpix(_pointD & pt)1686 _pointL preview_window::inches2clientpix ( _pointD & pt )
1687 {
1688 _pointD pt_tmp;
1689 _pointL pt_result;
1690 double da, db;
1691
1692 pt_tmp.x = pt.x - m_img_rect.left;
1693 pt_tmp.y = pt.y - m_img_rect.top;
1694
1695 da = m_img_rect.right - m_img_rect.left;
1696 db = m_client_rect.right - m_client_rect.left;
1697 pt_result.x = ( long ) similarity ( pt_tmp.x, da, db );
1698
1699 da = m_img_rect.bottom - m_img_rect.top;
1700 db = m_client_rect.bottom - m_client_rect.top;
1701 pt_result.y = ( long ) similarity ( pt_tmp.y, da, db );
1702
1703 return pt_result;
1704 }
1705
1706 /*--------------------------------------------------------------*/
get_marquee_point(long i,_pointL * pt_lt,_pointL * pt_rb)1707 int preview_window::get_marquee_point ( long i, _pointL * pt_lt, _pointL * pt_rb )
1708 {
1709 marquee * marq;
1710 _pointD pt_tmp_lt, pt_tmp_rb;
1711
1712 if (0 == (marq = & g_view_manager->get_marquee (i)))
1713 return 0;
1714
1715 pt_tmp_lt = marq->offset;
1716 pt_tmp_rb = marq->offset + marq->area;
1717
1718 * pt_lt = inches2clientpix ( pt_tmp_lt );
1719 * pt_rb = inches2clientpix ( pt_tmp_rb );
1720
1721 return 1;
1722 }
1723
1724 /*--------------------------------------------------------------*/
check_min_size(const _pointL & pt_lt,const _pointL & pt_rb)1725 int preview_window::check_min_size ( const _pointL & pt_lt, const _pointL & pt_rb )
1726 {
1727 _pointD pt_zero_D, pt_min_D;
1728 _pointL pt_min_L;
1729
1730 pt_zero_D.x = 0.0;
1731 pt_zero_D.y = 0.0;
1732 pt_min_D.x = g_min_marq_size;
1733 pt_min_D.y = g_min_marq_size;
1734 pt_min_L = inches2clientpix ( pt_min_D ) - inches2clientpix ( pt_zero_D );
1735
1736 if ( ::abs ( pt_lt.x - pt_rb.x ) < pt_min_L.x ||
1737 ::abs ( pt_lt.y - pt_rb.y ) < pt_min_L.y )
1738 return 0;
1739 else
1740 return 1;
1741 }
1742
1743 /*--------------------------------------------------------------*/
check_max_size(_pointD * pt_offset,_pointD * pt_area,int offset)1744 void preview_window::check_max_size ( _pointD * pt_offset, _pointD * pt_area,
1745 int offset )
1746 {
1747 if ( pt_offset->x < 0.0 ) pt_offset->x = 0.0;
1748 if ( pt_offset->y < 0.0 ) pt_offset->y = 0.0;
1749
1750 if ( pt_area->x > m_max_img_rect.right ) pt_area->x = m_max_img_rect.right;
1751 if ( pt_area->y > m_max_img_rect.bottom ) pt_area->y = m_max_img_rect.bottom;
1752
1753 if ( offset )
1754 {
1755 if ( m_max_img_rect.right < pt_offset->x + pt_area->x )
1756 pt_area->x = m_max_img_rect.right - pt_offset->x;
1757 if ( m_max_img_rect.bottom < pt_offset->y + pt_area->y )
1758 pt_area->y = m_max_img_rect.bottom - pt_offset->y;
1759 }
1760 else
1761 {
1762 if ( m_max_img_rect.right < pt_offset->x + pt_area->x )
1763 pt_offset->x = m_max_img_rect.right - pt_area->x;
1764 if ( m_max_img_rect.bottom < pt_offset->y + pt_area->y )
1765 pt_offset->y = m_max_img_rect.bottom - pt_area->y;
1766 }
1767 }
1768
1769 /*--------------------------------------------------------------*/
check_ltrb(_pointL * pt_lt,_pointL * pt_rb)1770 void preview_window::check_ltrb ( _pointL * pt_lt, _pointL * pt_rb )
1771 {
1772 _pointL pt_ret_lt, pt_ret_rb;
1773
1774 pt_ret_lt.x = ( pt_lt->x < pt_rb->x ) ? pt_lt->x : pt_rb->x;
1775 pt_ret_lt.y = ( pt_lt->y < pt_rb->y ) ? pt_lt->y : pt_rb->y;
1776 pt_ret_rb.x = ( pt_lt->x > pt_rb->x ) ? pt_lt->x : pt_rb->x;
1777 pt_ret_rb.y = ( pt_lt->y > pt_rb->y ) ? pt_lt->y : pt_rb->y;
1778
1779 * pt_lt = pt_ret_lt;
1780 * pt_rb = pt_ret_rb;
1781 }
1782
1783 /*--------------------------------------------------------------*/
draw_rect(const _pointL & pt_lt,const _pointL & pt_rb)1784 void preview_window::draw_rect ( const _pointL & pt_lt,
1785 const _pointL & pt_rb )
1786 {
1787 int x, y, w, h;
1788
1789 if ( m_gc == 0 )
1790 {
1791 m_gc = ::gdk_gc_new ( m_prev->window );
1792 ::gdk_gc_set_function ( m_gc, GDK_INVERT );
1793 ::gdk_gc_set_line_attributes ( m_gc, 1, GDK_LINE_ON_OFF_DASH,
1794 GDK_CAP_BUTT, GDK_JOIN_MITER );
1795 }
1796
1797 x = ( pt_lt.x < pt_rb.x ) ? pt_lt.x : pt_rb.x;
1798 y = ( pt_lt.y < pt_rb.y ) ? pt_lt.y : pt_rb.y;
1799 w = ( pt_lt.x > pt_rb.x ) ? pt_lt.x - pt_rb.x : pt_rb.x - pt_lt.x;
1800 h = ( pt_lt.y > pt_rb.y ) ? pt_lt.y - pt_rb.y : pt_rb.y - pt_lt.y;
1801
1802 ::gdk_draw_rectangle ( m_prev->window, m_gc, FALSE,
1803 x, y, w, h );
1804 }
1805
1806
1807