aboutsummaryrefslogtreecommitdiff
path: root/frontend/pisa_preview_window.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/pisa_preview_window.cc')
-rw-r--r--frontend/pisa_preview_window.cc1844
1 files changed, 1844 insertions, 0 deletions
diff --git a/frontend/pisa_preview_window.cc b/frontend/pisa_preview_window.cc
new file mode 100644
index 0000000..1928179
--- /dev/null
+++ b/frontend/pisa_preview_window.cc
@@ -0,0 +1,1844 @@
+/* pisa_preview_window.cc
+ Copyright (C) 2001, 2004, 2005, 2008, 2009 SEIKO EPSON CORPORATION
+
+ This file is part of the `iscan' program.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ As a special exception, the copyright holders give permission
+ to link the code of this program with the esmod library and
+ distribute linked combinations including the two. You must obey
+ the GNU General Public License in all respects for all of the
+ code used other then esmod.
+*/
+
+/*------------------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*------------------------------------------------------------*/
+#include "pisa_view_manager.h"
+#include "pisa_preview_window.h"
+#include "pisa_error.h"
+#include "pisa_scan_tool.h"
+#include "pisa_tool.h"
+#include "pisa_default_val.h"
+#include "pisa_aleart_dialog.h"
+#include "pisa_change_unit.h"
+
+/*------------------------------------------------------------*/
+long g_prev_max_x = 320;
+long g_prev_max_y = 440;
+
+const double g_min_marq_size = 0.4;
+
+/*------------------------------------------------------------*/
+static gint expose_event ( GtkWidget * widget,
+ GdkEventExpose * event )
+{
+ preview_window * prev_cls;
+
+ prev_cls = ( preview_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_PREV );
+
+ return prev_cls->expose_event ( widget, event );
+}
+
+
+/*------------------------------------------------------------*/
+static gint event ( GtkWidget * widget,
+ GdkEvent * event )
+{
+ preview_window * prev_cls;
+
+ prev_cls = ( preview_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_PREV );
+
+ return prev_cls->event ( widget, event );
+}
+
+/*------------------------------------------------------------*/
+static void size_allocate ( GtkWidget * widget )
+{
+ preview_window * prev_cls;
+
+ prev_cls = ( preview_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_PREV );
+
+ prev_cls->size_allocate ( widget );
+}
+
+/*------------------------------------------------------------*/
+int preview_window::init ( void )
+{
+ int i;
+
+ m_gc = 0;
+
+ m_img_width = g_prev_max_x;
+ m_img_height = g_prev_max_y;
+
+ m_is_prev = 0;
+ m_drag = 0;
+
+ m_img = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
+
+ if ( m_img == 0 )
+ return PISA_ERR_OUTOFMEMORY;
+
+ m_img_org = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
+
+ if ( m_img_org == 0 )
+ {
+ delete [ ] m_img;
+ m_img = 0;
+ return PISA_ERR_OUTOFMEMORY;
+ }
+
+ for ( i = 0; i < 11; i++ )
+ m_cursor [ i ] = 0;
+
+ m_on_preview = false;
+ m_allocate_width = 0;
+ m_allocate_height = 0;
+
+ return PISA_ERR_SUCCESS;
+}
+
+/*------------------------------------------------------------*/
+GtkWidget * preview_window::create_window ( GtkWidget * parent )
+{
+ m_win = create_darea ( parent );
+
+ create_cursor ( );
+
+ return m_win;
+}
+
+/*------------------------------------------------------------*/
+int preview_window::close_window ( int destroy )
+{
+ destroy = destroy;
+
+ if ( m_gc )
+ {
+ ::gdk_gc_destroy ( m_gc );
+ m_gc = 0;
+ }
+
+ if ( m_img )
+ {
+ delete [ ] m_img;
+ m_img = 0;
+ }
+
+ if ( m_img_org )
+ {
+ delete [ ] m_img_org;
+ m_img_org = 0;
+ }
+
+ return PISA_ERR_SUCCESS;
+}
+
+/*------------------------------------------------------------*/
+int preview_window::resize_window ( void )
+{
+ get_preview_resolution ( );
+ resize_preview_window ( 0, 0 );
+
+ clear_image ( );
+
+ return 0;
+}
+
+/*------------------------------------------------------------*/
+int preview_window::auto_exposure ( void )
+{
+ pisa_image_info info;
+ _rectL region;
+ marquee tmp_marq, * marq;
+ int i, marq_num;
+
+ scan_manager *scan_mgr = g_view_manager->get_scan_manager ();
+
+ if ( m_is_prev == 0 ||
+ g_view_manager->get_settings ().imgtype.pixeltype == PISA_PT_BW )
+ {
+ return PISA_ERR_SUCCESS;
+ }
+
+ info.m_img = m_img_org;
+ info.m_width = m_img_width;
+ info.m_height = m_img_height;
+ info.m_rowbytes = g_prev_max_x * 3;
+
+ marq_num = g_view_manager->get_marquee_size ();
+ marq = & g_view_manager->get_marquee ();
+
+ if ( marq_num < 2 )
+ {
+ region.left = 0;
+ region.top = 0;
+ region.right = m_img_width - 1;
+ region.bottom = m_img_height - 1;
+ }
+ else
+ {
+ _pointL pt_lt, pt_rb;
+
+ get_marquee_point ( marq_num - 1, & pt_lt, & pt_rb );
+
+ region.left = pt_lt.x;
+ region.top = pt_lt.y;
+ region.right = pt_rb.x;
+ region.bottom = pt_rb.y;
+ }
+
+ settings set = g_view_manager->get_settings ();
+ scan_manager *sm = g_view_manager->get_scan_manager ();
+ iscan::auto_expose (sm->get_scan_source (),
+ sm->get_film_type (),
+ info, region, tmp_marq,
+ set.imgtype.ae_option != PISA_AE_DOC,
+ !scan_mgr->has_zoom ());
+
+ marq->gamma = tmp_marq.gamma;
+ marq->highlight = tmp_marq.highlight;
+ marq->shadow = tmp_marq.shadow;
+ marq->graybalance = tmp_marq.graybalance;
+
+ for ( i = 0; i < 3; i++ )
+ {
+ marq->film_gamma [ i ] = tmp_marq.film_gamma [ i ];
+ marq->film_yp [ i ] = tmp_marq.film_yp [ i ];
+ marq->grayl [ i ] = tmp_marq.grayl [ i ];
+ }
+
+ ::g_view_manager->sensitive ( );
+ ::g_view_manager->update_lut ( );
+
+ return PISA_ERR_SUCCESS;
+}
+
+/*------------------------------------------------------------*/
+int preview_window::update_img ( bool left )
+{
+ int i;
+ pisa_image_info img_info;
+ marquee * marq;
+ double delta;
+ long curr_width, adj_width, resolution;
+
+ if ( m_is_prev == 0 )
+ {
+ clear_image ( );
+ return PISA_ERR_SUCCESS;
+ }
+
+ settings set = g_view_manager->get_settings ();
+ marq = & g_view_manager->get_marquee ();
+
+ resolution = (set.resolution * (marq->scale)) / 100;
+ curr_width = ::inch2pixel ( marq->area.x, resolution );
+ adj_width = ::inch2width ( marq->area.x, resolution );
+ delta = marq->area.x - (marq->area.x) * adj_width /curr_width ;
+
+ // Resize the area
+ marq -> area.x -= delta;
+ if ( left )
+ {
+ // If the left side -> increase the x offset
+ marq ->offset.x += delta;
+ }
+
+ if ( m_img == 0 || m_img_org == 0 )
+ return PISA_ERR_OUTOFMEMORY;
+
+ ::memcpy ( m_img, m_img_org, g_prev_max_x * g_prev_max_y * 3 );
+
+ img_info.m_img = m_img;
+ img_info.m_width = m_img_width;
+ img_info.m_height = m_img_height;
+ img_info.m_rowbytes = g_prev_max_x * 3;
+
+ ::tool_lut ( & img_info, & marq->lut );
+
+ switch (set.imgtype.pixeltype)
+ {
+ case PISA_PT_RGB:
+ tool_matrix (&img_info, marq->saturation, set.coef);
+ if (set.usm)
+ tool_usm (img_info);
+ break;
+
+ case PISA_PT_GRAY:
+ build_gray (&img_info, set.imgtype.dropout);
+ if (set.usm)
+ tool_usm (img_info);
+ break;
+
+ case PISA_PT_BW:
+ build_bw (&img_info,
+ set.imgtype.dropout,
+ set.imgtype.halftone,
+ marq->threshold);
+ break;
+ }
+
+ for ( i = 0; i < m_img_height; i++ )
+ ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ),
+ m_img + i * g_prev_max_x * 3,
+ 0, i, m_img_width );
+
+ ::gtk_widget_draw ( m_prev, 0 );
+ ::gdk_flush ( );
+
+ return PISA_ERR_SUCCESS;
+}
+
+void
+preview_window::start_preview (bool zooming)
+{
+ scan_manager * scan_mgr =
+ g_view_manager->get_scan_manager ( );
+ int width, height;
+ int cancel;
+
+ cancel = 0;
+
+ m_is_prev = 0;
+
+ m_on_preview = true;
+ m_allocate_width = 0;
+ m_allocate_height = 0;
+
+ progress_window feedback
+ (static_cast <main_window *> (g_view_manager
+ ->get_window_cls (ID_WINDOW_MAIN))
+ ->get_widget());
+ if (scan_mgr->push_button_needs_polling ())
+ {
+ feedback.set_text (progress_window::WAITING);
+ }
+ else
+ {
+ feedback.set_text (progress_window::WARMING_UP);
+ }
+ feedback.show ();
+
+ while ( ::gtk_events_pending ( ) )
+ ::gtk_main_iteration ( );
+
+ // preview
+ set_preview_param (zooming);
+
+ reset_settings (zooming);
+ ::g_view_manager->sensitive ( );
+
+ try
+ {
+ if (scan_mgr->push_button_needs_polling ())
+ {
+ long usec = scan_mgr->get_polling_time ();
+ while (!scan_mgr->is_button_pressed ()
+ && !feedback.is_cancelled ()) {
+ g_view_manager->microsleep (usec);
+ while (::gtk_events_pending ()) {
+ ::gtk_main_iteration ();
+ }
+ }
+ if (feedback.is_cancelled ())
+ {
+ return;
+ }
+ scan_mgr->disable_wait_for_button();
+ }
+
+ scan_mgr->init_preview (&width, &height);
+
+ if (!zooming)
+ {
+ change_max_scan_area ( width, height );
+ ::g_view_manager->sensitive ( );
+ }
+
+ resize_preview_window ( width, height );
+ clear_image ( );
+
+ while ( ::gtk_events_pending ( ) )
+ ::gtk_main_iteration ( );
+
+ for (int i = 0; i < height; i++ )
+ {
+ scan_mgr->acquire_image ( m_img_org + i * g_prev_max_x * 3,
+ width * 3,
+ 1,
+ cancel );
+
+ if ( i == 0 )
+ feedback.set_text (progress_window::PREVIEWING);
+
+ if (cancel)
+ break;
+
+ feedback.set_progress (i, height);
+ cancel = feedback.is_cancelled ();
+
+ ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ),
+ m_img_org + i * g_prev_max_x * 3,
+ 0, i, width );
+ if ( i % 20 == 0 )
+ {
+ ::gtk_preview_put ( GTK_PREVIEW ( m_prev ),
+ m_prev->window,
+ m_prev->style->black_gc,
+ 0, 0, 0, 0, width, height );
+ }
+
+ while ( ::gtk_events_pending ( ) )
+ ::gtk_main_iteration ( );
+ }
+ scan_mgr->acquire_image (0, 1, 1, cancel);
+ feedback.set_progress (height, height);
+ cancel = feedback.is_cancelled ();
+ if (cancel)
+ {
+ m_on_preview = false;
+ update_img ( );
+ change_max_disp_area ( m_allocate_width, m_allocate_height );
+ m_allocate_width = 0;
+ m_allocate_height = 0;
+ }
+ else
+ {
+ m_is_prev = 1;
+ ::gtk_widget_draw ( m_prev, 0 );
+ ::gdk_flush ( );
+
+ m_on_preview = false;
+
+ auto_exposure ( );
+ update_img ( );
+ change_max_disp_area ( m_allocate_width, m_allocate_height );
+ m_allocate_width = 0;
+ m_allocate_height = 0;
+ }
+ }
+ catch ( const pisa_error & err )
+ {
+ main_window * main_cls;
+ aleart_dialog aleart_dlg;
+
+ if ( PISA_STATUS_CANCELLED != err.get_error_id() )
+ {
+ main_cls = ( main_window * ) ::g_view_manager->get_window_cls ( ID_WINDOW_MAIN );
+ aleart_dlg.message_box ( main_cls->get_widget ( ),
+ err.get_error_string ( ) );
+ }
+
+ delete_marquee ( );
+
+ m_on_preview = false;
+ update_img ( );
+ change_max_disp_area ( m_allocate_width, m_allocate_height );
+ m_allocate_width = 0;
+ m_allocate_height = 0;
+ }
+
+ revert_resolution ();
+
+ scan_mgr->release_memory ();
+ scan_mgr->finish_acquire (true);
+
+ ::g_view_manager->sensitive ( );
+
+ {
+ gint x, y;
+ ::gdk_window_get_pointer ( m_prev->window, & x, & y, 0 );
+ set_mouse_cursor ( x, y );
+ change_cursor ( );
+ }
+}
+
+/*--------------------------------------------------------------*/
+gint preview_window::expose_event ( GtkWidget * widget,
+ GdkEventExpose * event )
+{
+ widget = widget;
+ event = event;
+
+ draw_marquee ( );
+
+ return FALSE;
+}
+
+/*--------------------------------------------------------------*/
+gint preview_window::event ( GtkWidget * widget, GdkEvent * event )
+{
+ gint ret;
+
+ widget = widget;
+
+ switch ( event->type )
+ {
+ case GDK_EXPOSE:
+ if ( m_gc )
+ {
+ draw_marquee ( );
+ }
+ ret = FALSE;
+ break;
+
+ case GDK_BUTTON_PRESS:
+ ret = mouse_down ( event );
+ ::gtk_grab_add ( widget );
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ ret = mouse_move ( event );
+ break;
+
+ case GDK_BUTTON_RELEASE:
+ ret = mouse_up ( event );
+ ::gtk_grab_remove ( widget );
+ break;
+
+ default:
+ ret = TRUE;
+ break;
+ }
+
+ return ret;
+}
+
+/*------------------------------------------------------------*/
+void preview_window::size_allocate ( GtkWidget * widget )
+{
+ int x, y;
+
+ x = widget->allocation.width;
+ y = widget->allocation.height;
+
+ if ( m_on_preview )
+ {
+ m_allocate_width = x;
+ m_allocate_height = y;
+ return;
+ }
+
+ change_max_disp_area ( x, y );
+}
+
+
+/*------------------------------------------------------------*/
+GtkWidget * preview_window::create_darea ( GtkWidget * parent )
+{
+ GtkWidget * frame;
+
+ parent = parent;
+
+ frame = ::gtk_frame_new ( 0 );
+ ::gtk_frame_set_shadow_type ( GTK_FRAME ( frame ), GTK_SHADOW_IN );
+ ::gtk_container_border_width ( GTK_CONTAINER ( frame ), 3 );
+
+ m_prev = ::gtk_preview_new ( GTK_PREVIEW_COLOR );
+ ::gtk_preview_set_expand ( GTK_PREVIEW ( m_prev ), TRUE );
+
+ // set size of preview window
+ get_preview_resolution ( );
+ resize_preview_window ( m_img_width, m_img_height );
+
+ ::gtk_container_add ( GTK_CONTAINER ( frame ), m_prev );
+ ::gtk_widget_show ( m_prev );
+
+ clear_image ( );
+
+ // signals
+ ::gtk_signal_connect ( GTK_OBJECT ( m_prev ), "event",
+ GTK_SIGNAL_FUNC ( ::event ), 0 );
+ ::gtk_signal_connect_after ( GTK_OBJECT ( m_prev ), "expose_event",
+ GTK_SIGNAL_FUNC ( ::expose_event ), 0 );
+ ::gtk_signal_connect_after ( GTK_OBJECT ( m_prev ), "size_allocate",
+ GTK_SIGNAL_FUNC ( ::size_allocate ), 0 );
+
+ ::gtk_widget_set_events ( m_prev ,
+ GDK_EXPOSURE_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_RELEASE_MASK );
+
+ return frame;
+}
+
+
+/*------------------------------------------------------------*/
+long preview_window::get_preview_resolution ( const _rectD * img_rect )
+{
+ long resolution;
+ _pointD pt_scan_size;
+ double aspect_max;
+ double aspect_scan;
+
+ if ( img_rect )
+ {
+ pt_scan_size.x = img_rect->right - img_rect->left;
+ pt_scan_size.y = img_rect->bottom - img_rect->top;
+ m_img_rect = * img_rect;
+ }
+ else
+ {
+ pt_scan_size.x = g_view_manager->get_settings ().max_area [ 0 ];
+ pt_scan_size.y = g_view_manager->get_settings ().max_area [ 1 ];
+
+ m_img_rect.left = 0.0;
+ m_img_rect.top = 0.0;
+ m_img_rect.right = pt_scan_size.x;
+ m_img_rect.bottom = pt_scan_size.y;
+ }
+
+ aspect_max = ( float ) g_prev_max_y / g_prev_max_x;
+ aspect_scan = ( float ) pt_scan_size.y / pt_scan_size.x;
+
+ if ( aspect_max < aspect_scan )
+ resolution = ( long ) ( g_prev_max_y / pt_scan_size.y );
+ else
+ resolution = ( long ) ( g_prev_max_x / pt_scan_size.x );
+
+ m_img_width = ( long ) ( resolution * pt_scan_size.x );
+ m_img_height = ( long ) ( resolution * pt_scan_size.y );
+
+ return resolution;
+}
+
+/*------------------------------------------------------------*/
+void preview_window::resize_preview_window ( long width, long height )
+{
+ if ( width != 0 && height != 0 )
+ {
+ m_img_width = width;
+ m_img_height = height;
+ }
+
+ if ( m_img )
+ {
+ delete [ ] m_img;
+ m_img = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
+ }
+
+ if ( m_img_org )
+ {
+ delete [ ] m_img_org;
+ m_img_org = new unsigned char [ g_prev_max_x * g_prev_max_y * 3 ];
+ }
+
+ m_client_rect.left = 0;
+ m_client_rect.top = 0;
+ m_client_rect.right = m_img_width - 1;
+ m_client_rect.bottom = m_img_height - 1;
+
+ modify_max_val ( );
+}
+
+/*------------------------------------------------------------*/
+void preview_window::change_max_scan_area ( long width, long height )
+{
+ _pointD pt_scan_size;
+ marquee * marq;
+
+ if ( m_img_width < width || m_img_height < height )
+ return;
+
+ marq = & g_view_manager->get_marquee ();
+
+ pt_scan_size.x = g_view_manager->get_settings ().max_area [ 0 ];
+ pt_scan_size.y = g_view_manager->get_settings ().max_area [ 1 ];
+
+ m_img_rect.left = 0.0;
+ m_img_rect.top = 0.0;
+ m_img_rect.right = pt_scan_size.x * width / m_img_width;
+ m_img_rect.bottom = pt_scan_size.y * height / m_img_height;
+
+ marq->area.x = m_img_rect.right;
+ marq->area.y = m_img_rect.bottom;
+}
+
+/*------------------------------------------------------------*/
+void preview_window::change_max_disp_area ( long width, long height )
+{
+ long save_prev_x, save_prev_y;
+ long save_img_width, save_img_height;
+ unsigned char * save_img_org;
+ _rectD tmp_rect;
+
+ if ( width < 1 && height < 1 )
+ return;
+
+ if ( g_prev_max_x == width && g_prev_max_y == height )
+ return;
+
+ tmp_rect = m_img_rect;
+
+ if ( m_is_prev == 0 )
+ {
+ g_prev_max_x = width;
+ g_prev_max_y = height;
+
+ get_preview_resolution ( & tmp_rect );
+ resize_preview_window ( 0, 0 );
+
+ clear_image ( );
+
+ return;
+ }
+
+ // save old parameter and image
+ save_prev_x = g_prev_max_x;
+ save_prev_y = g_prev_max_y;
+ save_img_width = m_img_width;
+ save_img_height = m_img_height;
+ save_img_org = new unsigned char [ save_prev_x * save_prev_y * 3 ];
+
+ if ( save_img_org )
+ {
+ ::memcpy ( save_img_org, m_img_org, save_prev_x * save_prev_y * 3 );
+ }
+
+ // resize
+ g_prev_max_x = width;
+ g_prev_max_y = height;
+
+ get_preview_resolution ( & tmp_rect );
+ resize_preview_window ( 0, 0 );
+
+ clear_image ( );
+ m_is_prev = 1;
+
+ // restore image
+ if ( save_img_org )
+ {
+ struct resize_img_info parms;
+
+ parms.in_width = save_img_width;
+ parms.in_height = save_img_height;
+ parms.in_rowbytes = save_prev_x * 3;
+ parms.out_width = m_img_width;
+ parms.out_height = m_img_height;
+ parms.out_rowbytes = g_prev_max_x * 3;
+ parms.bits_per_pixel = 24;
+ parms.resize_flag = PISA_RS_BL;
+ parms.resolution = 0; // just to make sure it's set
+
+ iscan::scale f (parms);
+
+ f.exec (save_img_org, parms.in_height * parms.in_rowbytes,
+ m_img_org, parms.out_height * parms.out_rowbytes);
+
+ delete [] save_img_org;
+ }
+
+ update_img ( );
+}
+
+/*------------------------------------------------------------*/
+void preview_window::clear_image ( void )
+{
+ int i;
+
+ m_is_prev = 0;
+
+ ::memset ( m_img, 0xff, m_img_width * 3 );
+ ::memset ( m_img + ( m_img_width * 3 ),
+ 0xC4,
+ ( g_prev_max_x - m_img_width ) * 3 );
+
+ for ( i = 0; i < m_img_height; i++ )
+ ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ), m_img,
+ 0, i, g_prev_max_x );
+
+ ::memset ( m_img, 0xC4, g_prev_max_x * 3 );
+
+ for ( ; i < g_prev_max_y; i++ )
+ ::gtk_preview_draw_row ( GTK_PREVIEW ( m_prev ), m_img,
+ 0, i, g_prev_max_x );
+
+ ::gtk_widget_draw ( m_prev, 0 );
+ ::gdk_flush ( );
+}
+
+
+/*--------------------------------------------------------------*/
+void preview_window::draw_marquee ( void )
+{
+ long i, marq_num;
+ _pointL pt_lefttop, pt_rightbottom;
+
+ if ( m_gc == 0 )
+ {
+ m_gc = ::gdk_gc_new ( m_prev->window );
+ ::gdk_gc_set_function ( m_gc, GDK_INVERT );
+ ::gdk_gc_set_line_attributes ( m_gc, 1, GDK_LINE_ON_OFF_DASH,
+ GDK_CAP_BUTT, GDK_JOIN_MITER );
+ }
+
+ marq_num = g_view_manager->get_settings ().get_marquee_size ( );
+
+ if ( marq_num < 2 || m_on_preview )
+ return;
+
+ for ( i = 1; i < marq_num; i++ )
+ {
+ get_marquee_point ( i, & pt_lefttop, & pt_rightbottom );
+
+ draw_rect ( pt_lefttop, pt_rightbottom );
+ }
+}
+
+/*--------------------------------------------------------------*/
+void
+preview_window::reset_settings (bool zooming)
+{
+ long i, n, m, marq_num;
+ marquee * marq;
+ gamma_correction * gamma_cls;
+ scan_manager * scan_mgr;
+
+ gamma_cls = g_view_manager->get_gamma_correction ();
+
+ scan_mgr = g_view_manager->get_scan_manager ();
+ marq_num = g_view_manager->get_marquee_size ();
+
+ if (!zooming)
+ {
+ while ( 1 < marq_num )
+ {
+ g_view_manager->del_marquee (marq_num - 1);
+ marq_num = g_view_manager->get_marquee_size ();
+ }
+
+ gamma_cls->reset ( 1 );
+ }
+
+ marq_num = g_view_manager->get_marquee_size ();
+
+ for ( i = 0; i < marq_num; i++ )
+ {
+ marq = & g_view_manager->get_marquee (i);
+
+ if (!zooming)
+ {
+ marq->gamma = ( long ) ( 100 * DEFGAMMA );
+ marq->highlight = DEFHIGHLIGHT;
+ marq->shadow = DEFSHADOW;
+ marq->threshold = DEFTHRESHOLD;
+
+ for ( n = 0; n < 4; n++ )
+ for ( m = 0; m < 256; m++ )
+ marq->gamma_table [ n ] [ m ] = m;
+
+ marq->graybalance = DEFGRAYBALANCE;
+ marq->saturation = DEFSATURATION;
+ }
+
+ for ( n = 0; n < 3; n++ )
+ {
+ marq->film_gamma [ n ] = 1.0;
+ marq->film_yp [ n ] = 0.0;
+ marq->grayl [ n ] = 0.0;
+ }
+
+ iscan::build_LUT (scan_mgr->get_scan_source (),
+ scan_mgr->get_film_type (),
+ g_view_manager->get_settings (),
+ *marq, !scan_mgr->has_zoom ());
+ }
+}
+
+int
+preview_window::set_preview_param (bool zooming)
+{
+ settings set = g_view_manager->get_settings ();
+ marquee marq;
+
+ if (!zooming)
+ {
+ marq.offset.x = 0.0;
+ marq.offset.y = 0.0;
+ marq.area.x = set.max_area[0];
+ marq.area.y = set.max_area[1];
+ }
+ else
+ {
+ float rate = 0.1f;
+ _pointD pt_offset, pt_area, pt_max;
+
+ marquee cur_marq = g_view_manager->get_marquee ();
+
+ marq.focus = cur_marq.focus;
+
+ pt_offset = cur_marq.offset;
+ pt_area = cur_marq.area;
+
+ marquee whole_marq = g_view_manager->get_marquee (0);
+
+ pt_max.x = whole_marq.area.x;
+ pt_max.y = whole_marq.area.y;
+
+ zoom_boundary (pt_offset, pt_area, pt_max, rate);
+
+ marq.offset.x = pt_offset.x;
+ marq.offset.y = pt_offset.y;
+ marq.area.x = pt_area.x;
+ marq.area.y = pt_area.y;
+ }
+
+ _rectD img_rect;
+ img_rect.left = marq.offset.x;
+ img_rect.top = marq.offset.y;
+ img_rect.right = marq.offset.x + marq.area.x;
+ img_rect.bottom = marq.offset.y + marq.area.y;
+
+ long resolution = get_preview_resolution (&img_rect);
+
+ pisa_error_id err = (g_view_manager->get_scan_manager ()
+ ->set_scan_parameters (set, marq, resolution));
+
+ return err;
+}
+
+void
+preview_window::revert_resolution ( void )
+{
+ long set_res = g_view_manager->get_settings ().resolution;
+
+ g_view_manager->set_resolution (set_res);
+}
+
+/*------------------------------------------------------------*/
+void preview_window::tool_usm (const pisa_image_info& info)
+{
+ iscan::focus f (info);
+
+ f.exec (info.m_img, info.m_height * info.m_rowbytes,
+ info.m_img, info.m_height * info.m_rowbytes);
+}
+
+void
+preview_window::zoom_boundary (_pointD& pt_offset, _pointD& pt_area,
+ const _pointD& pt_max, float rate) const
+{
+ _pointD pt_result_offset, pt_result_area;
+ double bound_size;
+
+ if (pt_area.x < pt_area.y)
+ bound_size = pt_area.y * rate;
+ else
+ bound_size = pt_area.x * rate;
+
+ bound_size = (0.0 == bound_size) ? 0.01 : bound_size;
+
+ // left
+ pt_result_offset.x = pt_offset.x - bound_size;
+ if (0.0 > pt_result_offset.x)
+ pt_result_offset.x = 0.0;
+
+ // top
+ pt_result_offset.y = pt_offset.y - bound_size;
+ if (0.0 > pt_result_offset.y)
+ pt_result_offset.y = 0.0;
+
+ // right
+ pt_result_area.x = ((pt_offset.x - pt_result_offset.x) +
+ pt_area.x + bound_size);
+ if (pt_max.x < pt_result_offset.x + pt_result_area.x)
+ pt_result_area.x = pt_max.x - pt_result_offset.x;
+
+ // bottom
+ pt_result_area.y = ((pt_offset.y - pt_result_offset.y) +
+ pt_area.y + bound_size);
+ if (pt_max.y < pt_result_offset.y + pt_result_area.y)
+ pt_result_area.y = pt_max.y - pt_result_offset.y;
+
+ pt_offset = pt_result_offset;
+ pt_area = pt_result_area;
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::create_cursor ( void )
+{
+ m_cursor [ PISA_CS_ARROW ] = ::gdk_cursor_new ( GDK_ARROW );
+ m_cursor [ PISA_CS_HAND ] = ::gdk_cursor_new ( GDK_HAND2 );
+ m_cursor [ PISA_CS_CROSS ] = ::gdk_cursor_new ( GDK_CROSS );
+ m_cursor [ PISA_CS_TOP ] = ::gdk_cursor_new ( GDK_TOP_SIDE );
+ m_cursor [ PISA_CS_BOTTOM ] = ::gdk_cursor_new ( GDK_BOTTOM_SIDE );
+ m_cursor [ PISA_CS_LEFT ] = ::gdk_cursor_new ( GDK_LEFT_SIDE );
+ m_cursor [ PISA_CS_RIGHT ] = ::gdk_cursor_new ( GDK_RIGHT_SIDE );
+ m_cursor [ PISA_CS_LEFTTOP ] = ::gdk_cursor_new ( GDK_TOP_LEFT_CORNER );
+ m_cursor [ PISA_CS_LEFTBOTTOM ] = ::gdk_cursor_new ( GDK_BOTTOM_LEFT_CORNER );
+ m_cursor [ PISA_CS_RIGHTTOP ] = ::gdk_cursor_new ( GDK_TOP_RIGHT_CORNER );
+ m_cursor [ PISA_CS_RIGHTBOTTOM ] = ::gdk_cursor_new ( GDK_BOTTOM_RIGHT_CORNER );
+}
+
+
+/*--------------------------------------------------------------*/
+int preview_window::set_mouse_cursor ( int x, int y )
+{
+ const long ADDSIZE = 3;
+ long marq_num;
+ _pointL pt_lefttop, pt_rightbottom;
+ int cursor_state;
+ _pointL pt;
+ int pt_in_cur_marq;
+ _rectL judge_rect;
+ _pointL pt_lt, pt_rb;
+ int i;
+
+ if ( m_drag == 1 )
+ return FALSE;
+
+ pt.x = x;
+ pt.y = y;
+
+ if ( 0 == ::pt_in_rect ( m_client_rect, pt ) )
+ {
+ m_cursor_state = PISA_CS_ARROW;
+ return FALSE;
+ }
+
+ marq_num = g_view_manager->get_settings ().get_marquee_size ( );
+
+ if ( marq_num < 2 )
+ {
+ m_cursor_state = PISA_CS_CROSS;
+ return FALSE;
+ }
+
+ get_marquee_point ( marq_num - 1, & pt_lefttop, & pt_rightbottom );
+
+ cursor_state = search_cursor_state ( pt_lefttop, pt_rightbottom, pt );
+ if ( cursor_state != PISA_CS_CROSS )
+ {
+ m_cursor_state = cursor_state;
+ return FALSE;
+ }
+
+ judge_rect.left = pt_lefttop.x;
+ judge_rect.right = pt_rightbottom.x;
+ judge_rect.top = pt_lefttop.y;
+ judge_rect.bottom = pt_rightbottom.y;
+ if ( pt_in_rect ( judge_rect, pt ) )
+ pt_in_cur_marq = 1;
+ else
+ pt_in_cur_marq = 0;
+
+ for ( i = marq_num - 1; 0 < i; i-- )
+ {
+ if ( marq_num - 1 == i )
+ continue;
+
+ get_marquee_point ( i, & pt_lt, & pt_rb );
+
+ if ( pt_in_cur_marq )
+ {
+ cursor_state = search_cursor_state ( pt_lt, pt_rb, pt );
+ if ( PISA_CS_CROSS != cursor_state )
+ {
+ m_cursor_state = PISA_CS_ARROW;
+ return i;
+ }
+ }
+ else
+ {
+ judge_rect.left = pt_lt.x - ADDSIZE;
+ judge_rect.right = pt_rb.x + ADDSIZE;
+ judge_rect.top = pt_lt.y - ADDSIZE;
+ judge_rect.bottom = pt_rb.y + ADDSIZE;
+ if ( pt_in_rect ( judge_rect, pt ) )
+ {
+ m_cursor_state = PISA_CS_ARROW;
+ return i;
+ }
+ }
+ }
+
+ if ( pt_in_cur_marq )
+ {
+ m_cursor_state = PISA_CS_HAND;
+ return 0;
+ }
+
+ m_cursor_state = PISA_CS_CROSS;
+
+ return 0;
+}
+
+/*--------------------------------------------------------------*/
+int preview_window::search_cursor_state ( const _pointL & pt_lt,
+ const _pointL & pt_rb,
+ const _pointL & pt )
+{
+ const long ADDSIZE = 3;
+ _rectL judge_rect;
+
+ // check left top
+ judge_rect.left = pt_lt.x - ADDSIZE;
+ judge_rect.right = pt_lt.x + ADDSIZE;
+ judge_rect.top = pt_lt.y - ADDSIZE;
+ judge_rect.bottom = pt_lt.y + ADDSIZE;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_LEFTTOP;
+
+ // check right bottom
+ judge_rect.left = pt_rb.x - ADDSIZE;
+ judge_rect.right = pt_rb.x + ADDSIZE;
+ judge_rect.top = pt_rb.y - ADDSIZE;
+ judge_rect.bottom = pt_rb.y + ADDSIZE;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_RIGHTBOTTOM;
+
+ // check right top
+ judge_rect.left = pt_rb.x - ADDSIZE;
+ judge_rect.right = pt_rb.x + ADDSIZE;
+ judge_rect.top = pt_lt.y - ADDSIZE;
+ judge_rect.bottom = pt_lt.y + ADDSIZE;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_RIGHTTOP;
+
+ // check left bottom
+ judge_rect.left = pt_lt.x - ADDSIZE;
+ judge_rect.right = pt_lt.x + ADDSIZE;
+ judge_rect.top = pt_rb.y - ADDSIZE;
+ judge_rect.bottom = pt_rb.y + ADDSIZE;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_LEFTBOTTOM;
+
+ // check left resizing
+ judge_rect.left = pt_lt.x - ADDSIZE;
+ judge_rect.right = pt_lt.x + ADDSIZE;
+ judge_rect.top = pt_lt.y;
+ judge_rect.bottom = pt_rb.y;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_LEFT;
+
+ // check right resizing
+ judge_rect.left = pt_rb.x - ADDSIZE;
+ judge_rect.right = pt_rb.x + ADDSIZE;
+ judge_rect.top = pt_lt.y;
+ judge_rect.bottom = pt_rb.y;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_RIGHT;
+
+ // check top resizing
+ judge_rect.left = pt_lt.x;
+ judge_rect.right = pt_rb.x;
+ judge_rect.top = pt_lt.y - ADDSIZE;
+ judge_rect.bottom = pt_lt.y + ADDSIZE;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_TOP;
+
+ // check bottom resizing
+ judge_rect.left = pt_lt.x;
+ judge_rect.right = pt_rb.x;
+ judge_rect.top = pt_rb.y - ADDSIZE;
+ judge_rect.bottom = pt_rb.y + ADDSIZE;
+ if ( ::pt_in_rect ( judge_rect, pt ) )
+ return PISA_CS_BOTTOM;
+
+ return PISA_CS_CROSS;
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::change_cursor ( void )
+{
+ ::gdk_window_set_cursor ( m_prev->window,
+ m_cursor [ m_cursor_state ] );
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::modify_max_val ( void )
+{
+ marquee * whole_marq;
+ _pointD pt_min_D, pt_max_D;
+
+ whole_marq = & g_view_manager->get_marquee (0);
+ m_max_img_rect.top = 0.0;
+ m_max_img_rect.left = 0.0;
+ m_max_img_rect.right = whole_marq->area.x;
+ m_max_img_rect.bottom = whole_marq->area.y;
+
+ pt_min_D.x = m_max_img_rect.left;
+ pt_min_D.y = m_max_img_rect.top;
+ pt_max_D.x = m_max_img_rect.right;
+ pt_max_D.y = m_max_img_rect.bottom;
+ m_pt_max_rb = inches2clientpix ( pt_max_D );
+ m_pt_max_lt.x = 0;
+ m_pt_max_lt.y = 0;
+ m_pt_max_rb.x = m_img_width - 1;
+ m_pt_max_rb.y = m_img_height - 1;
+}
+
+/*--------------------------------------------------------------*/
+gint preview_window::mouse_down ( GdkEvent * event )
+{
+ marquee * cur_marq;
+ _pointL pt_lefttop, pt_rightbottom;
+ long id_cur_marquee;
+
+ if ( event->button.button != 1 )
+ return TRUE;
+
+ if ( m_img_width - 1 < ( int ) event->button.x || m_img_height - 1 < ( int ) event->button.y )
+ return TRUE;
+
+ m_pt_begin.x = ( int ) event->button.x;
+ m_pt_begin.y = ( int ) event->button.y;
+
+ m_drag = 1;
+
+ m_pt_old = m_pt_begin;
+
+ id_cur_marquee = g_view_manager->get_marquee_size () - 1;
+ get_marquee_point ( id_cur_marquee, & pt_lefttop, & pt_rightbottom );
+
+ cur_marq = & g_view_manager->get_marquee ();
+
+ m_pt_save_offset = cur_marq->offset;
+ m_pt_save_area = cur_marq->area;
+
+ switch ( m_cursor_state )
+ {
+ case PISA_CS_CROSS:
+ m_pt_old_lt = m_pt_old_rb = m_pt_begin;
+ delete_marquee ( );
+ create_marquee ( m_pt_old_lt, m_pt_old_rb );
+ break;
+ case PISA_CS_HAND:
+ case PISA_CS_TOP:
+ case PISA_CS_BOTTOM:
+ case PISA_CS_LEFT:
+ case PISA_CS_RIGHT:
+ case PISA_CS_LEFTTOP:
+ case PISA_CS_LEFTBOTTOM:
+ case PISA_CS_RIGHTTOP:
+ case PISA_CS_RIGHTBOTTOM:
+ m_pt_old_lt = pt_lefttop;
+ m_pt_old_rb = pt_rightbottom;
+ break;
+ }
+
+ return FALSE;
+}
+
+/*--------------------------------------------------------------*/
+gint preview_window::mouse_move ( GdkEvent * event )
+{
+ int x, y;
+ GdkModifierType state;
+ _pointL pt_mouse, pt_move, pt_tmp_lt, pt_tmp_rb, pt_min_L;
+ _pointD pt_lefttop, pt_rightbottom, pt_min_D, pt_zero_D;
+
+ if ( event->motion.is_hint )
+ {
+ ::gdk_window_get_pointer ( m_prev->window, & x, & y, & state );
+ }
+ else
+ return TRUE;
+
+ if ( m_drag == 0 )
+ {
+ set_mouse_cursor ( x, y );
+ change_cursor ( );
+ return FALSE;
+ }
+
+ if ( x < 0 ) x = 0;
+ if ( y < 0 ) y = 0;
+ if ( m_client_rect.right < x ) x = m_client_rect.right;
+ if ( m_client_rect.bottom < y ) y = m_client_rect.bottom;
+
+ pt_mouse.x = x;
+ pt_mouse.y = y;
+
+ // clear previous marquee
+ draw_rect ( m_pt_old_lt, m_pt_old_rb );
+
+ pt_lefttop = m_pt_save_offset;
+ pt_rightbottom = m_pt_save_offset + m_pt_save_area;
+
+ pt_tmp_lt = inches2clientpix ( pt_lefttop );
+ pt_tmp_rb = inches2clientpix ( pt_rightbottom );
+
+ pt_zero_D.x = 0.0;
+ pt_zero_D.y = 0.0;
+ pt_min_D.x = g_min_marq_size;
+ pt_min_D.y = g_min_marq_size;
+ pt_min_L = inches2clientpix ( pt_min_D ) - inches2clientpix ( pt_zero_D );
+
+ pt_move = pt_mouse - m_pt_begin;
+
+ // initialize
+ begin_mouse_move ( & pt_tmp_lt, & pt_tmp_rb );
+
+ move_rect ( & pt_tmp_lt, & pt_tmp_rb, pt_move );
+
+ switch ( m_cursor_state )
+ {
+ case PISA_CS_CROSS:
+ m_pt_old_rb = pt_mouse;
+ break;
+ case PISA_CS_HAND:
+ m_pt_old_rb = pt_tmp_lt + ( m_pt_old_rb - m_pt_old_lt );
+ m_pt_old_lt = pt_tmp_lt;
+ break;
+ case PISA_CS_TOP:
+ if ( m_pt_old_rb.y - pt_min_L.y > pt_tmp_lt.y )
+ m_pt_old_lt.y = pt_tmp_lt.y;
+ else
+ m_pt_old_lt.y = m_pt_old_rb.y - pt_min_L.y;
+ break;
+ case PISA_CS_BOTTOM:
+ if ( m_pt_old_lt.y + pt_min_L.y < pt_tmp_rb.y )
+ m_pt_old_rb.y = pt_tmp_rb.y;
+ else
+ m_pt_old_rb.y = m_pt_old_lt.y + pt_min_L.y;
+ break;
+ case PISA_CS_LEFT:
+ if ( m_pt_old_rb.x - pt_min_L.x > pt_tmp_lt.x )
+ m_pt_old_lt.x = pt_tmp_lt.x;
+ else
+ m_pt_old_lt.x = m_pt_old_rb.x - pt_min_L.x;
+ break;
+ case PISA_CS_RIGHT:
+ if ( m_pt_old_lt.x + pt_min_L.x < pt_tmp_rb.x )
+ m_pt_old_rb.x = pt_tmp_rb.x;
+ else
+ m_pt_old_rb.x = m_pt_old_lt.x + pt_min_L.x;
+ break;
+ case PISA_CS_LEFTTOP:
+ if ( m_pt_old_rb.y - pt_min_L.y > pt_tmp_lt.y )
+ m_pt_old_lt.y = pt_tmp_lt.y;
+ else
+ m_pt_old_lt.y = m_pt_old_rb.y - pt_min_L.y;
+ if ( m_pt_old_rb.x - pt_min_L.x > pt_tmp_lt.x )
+ m_pt_old_lt.x = pt_tmp_lt.x;
+ else
+ m_pt_old_lt.x = m_pt_old_rb.x - pt_min_L.x;
+ break;
+ case PISA_CS_LEFTBOTTOM:
+ if ( m_pt_old_rb.x - pt_min_L.x > pt_tmp_lt.x )
+ m_pt_old_lt.x = pt_tmp_lt.x;
+ else
+ m_pt_old_lt.x = m_pt_old_rb.x - pt_min_L.x;
+ if ( m_pt_old_lt.y + pt_min_L.y < pt_tmp_rb.y )
+ m_pt_old_rb.y = pt_tmp_rb.y;
+ else
+ m_pt_old_rb.y = m_pt_old_lt.y + pt_min_L.y;
+ break;
+ case PISA_CS_RIGHTTOP:
+ if ( m_pt_old_rb.y - pt_min_L.y > pt_tmp_lt.y )
+ m_pt_old_lt.y = pt_tmp_lt.y;
+ else
+ m_pt_old_lt.y = m_pt_old_rb.y - pt_min_L.y;
+ if ( m_pt_old_lt.x + pt_min_L.x < pt_tmp_rb.x )
+ m_pt_old_rb.x = pt_tmp_rb.x;
+ else
+ m_pt_old_rb.x = m_pt_old_lt.x + pt_min_L.x;
+ break;
+ case PISA_CS_RIGHTBOTTOM:
+ if ( m_pt_old_lt.y + pt_min_L.y < pt_tmp_rb.y )
+ m_pt_old_rb.y = pt_tmp_rb.y;
+ else
+ m_pt_old_rb.y = m_pt_old_lt.y + pt_min_L.y;
+ if ( m_pt_old_lt.x + pt_min_L.x < pt_tmp_rb.x )
+ m_pt_old_rb.x = pt_tmp_rb.x;
+ else
+ m_pt_old_rb.x = m_pt_old_lt.x + pt_min_L.x;
+ break;
+ }
+
+ draw_rect ( m_pt_old_lt, m_pt_old_rb );
+
+ if ( m_cursor_state != PISA_CS_HAND )
+ resize_marquee ( m_pt_old_lt, m_pt_old_rb );
+
+ m_pt_old = pt_mouse;
+
+ return FALSE;
+}
+
+/*--------------------------------------------------------------*/
+gint preview_window::mouse_up ( GdkEvent * event )
+{
+ int min_check;
+ _pointL pt_mouse;
+ long marq_num;
+
+ if ( 0 == m_drag )
+ return FALSE;
+
+ pt_mouse.x = ( int ) event->button.x;
+ pt_mouse.y = ( int ) event->button.y;
+
+ // clear previous marquee
+ marq_num = g_view_manager->get_marquee_size ();
+ if ( 1 < marq_num )
+ draw_rect ( m_pt_old_lt, m_pt_old_rb );
+
+ switch ( m_cursor_state )
+ {
+ case PISA_CS_CROSS:
+ min_check = check_min_size ( m_pt_old_lt, m_pt_old_rb );
+ if ( min_check == 0 )
+ delete_marquee ( );
+ update_img ( );
+ break;
+ case PISA_CS_ARROW:
+ break;
+ case PISA_CS_HAND:
+ move_marquee ( m_pt_old_lt, m_pt_old_rb );
+ update_img ( );
+ break;
+ case PISA_CS_LEFT:
+ case PISA_CS_LEFTTOP:
+ case PISA_CS_LEFTBOTTOM:
+ case PISA_CS_RIGHT:
+ case PISA_CS_RIGHTTOP:
+ case PISA_CS_RIGHTBOTTOM:
+ case PISA_CS_TOP:
+ case PISA_CS_BOTTOM:
+ if ( 0 == check_min_size ( m_pt_old_lt, m_pt_old_rb ) )
+ delete_marquee ( );
+ update_img ( PISA_CS_LEFT == m_cursor_state
+ || PISA_CS_LEFTTOP == m_cursor_state
+ || PISA_CS_LEFTBOTTOM == m_cursor_state);
+ break;
+ }
+
+ m_drag = 0;
+
+ set_mouse_cursor ( pt_mouse.x, pt_mouse.y );
+ change_cursor ( );
+
+ return FALSE;
+}
+
+/*--------------------------------------------------------------*/
+int preview_window::create_marquee ( const _pointL & pt_lt, const _pointL & pt_rb )
+{
+ _pointL pt_lefttop_L, pt_rightbottom_L;
+ _pointD pt_lefttop_D, pt_rightbottom_D, pt_area_D;
+ marquee * new_marq, * whole_marq;
+
+ pt_lefttop_L = pt_lt;
+ pt_rightbottom_L = pt_rb;
+ check_ltrb ( & pt_lefttop_L, & pt_rightbottom_L );
+
+ pt_lefttop_D = clientpix2inches ( pt_lefttop_L );
+ pt_rightbottom_D = clientpix2inches ( pt_rightbottom_L );
+ pt_area_D = pt_rightbottom_D - pt_lefttop_D;
+
+ check_max_size ( & pt_lefttop_D, & pt_area_D, 0 );
+
+ whole_marq = & g_view_manager->get_marquee (0);
+ new_marq = new marquee;
+ * new_marq = * whole_marq;
+
+ new_marq->offset = pt_lefttop_D;
+ new_marq->area = pt_area_D;
+
+ g_view_manager->add_marquee (&new_marq);
+
+ ::g_view_manager->sensitive ( );
+
+ return 1;
+}
+
+/*--------------------------------------------------------------*/
+int preview_window::delete_marquee ( void )
+{
+ long num_marq;
+ int i, j;
+ marquee * cur_marq, * whole_marq;
+
+ num_marq = g_view_manager->get_marquee_size ();
+
+ // no marquee
+ if ( num_marq < 2 )
+ return PISA_ERR_SUCCESS;
+
+ whole_marq = & g_view_manager->get_marquee (0);
+ cur_marq = & g_view_manager->get_marquee ();
+
+ whole_marq->gamma = cur_marq->gamma;
+ whole_marq->highlight = cur_marq->highlight;
+ whole_marq->shadow = cur_marq->shadow;
+ whole_marq->threshold = cur_marq->threshold;
+
+ for ( i = 0; i < 4; i++ )
+ for ( j = 0; j < 256; j++ )
+ whole_marq->gamma_table [ i ] [ j ] = cur_marq->gamma_table [ i ] [ j ];
+
+ whole_marq->graybalance = cur_marq->graybalance;
+ whole_marq->saturation = cur_marq->saturation;
+
+ whole_marq->scale = cur_marq->scale;
+
+ whole_marq->focus = cur_marq->focus;
+
+ for ( i = 0; i < 3; i++ )
+ {
+ whole_marq->film_gamma [ i ] = cur_marq->film_gamma [ i ];
+ whole_marq->film_yp [ i ] = cur_marq->film_yp [ i ];
+ whole_marq->grayl [ i ] = cur_marq->grayl [ i ];
+ }
+
+ for ( i = 0; i < 256; i++ )
+ {
+ whole_marq->lut.gamma_r [ i ] = cur_marq->lut.gamma_r [ i ];
+ whole_marq->lut.gamma_g [ i ] = cur_marq->lut.gamma_g [ i ];
+ whole_marq->lut.gamma_b [ i ] = cur_marq->lut.gamma_b [ i ];
+ }
+
+ g_view_manager->del_marquee ();
+
+ ::g_view_manager->sensitive ( );
+ update_img ( );
+
+ return PISA_ERR_SUCCESS;
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::move_marquee ( const _pointL & pt_lt,
+ const _pointL & pt_rb )
+{
+ _pointL pt_lefttop_L, pt_rightbottom_L, pt_tmp;
+ _pointD pt_lefttop_D, pt_rightbottom_D, pt_offset, pt_area;
+ marquee * cur_marq;
+
+ pt_tmp = pt_rb;
+
+ pt_lefttop_L = pt_lt;
+ pt_lefttop_D = clientpix2inches ( pt_lefttop_L );
+ pt_rightbottom_D = clientpix2inches ( pt_rightbottom_L );
+
+ pt_offset = pt_lefttop_D;
+ pt_area = pt_rightbottom_D - pt_lefttop_D;
+
+ check_max_size ( & pt_offset, & pt_area, 1 );
+
+ cur_marq = & g_view_manager->get_marquee ();
+
+ cur_marq->offset = pt_offset;
+
+ ::g_view_manager->sensitive ( );
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::resize_marquee ( const _pointL & pt_lt,
+ const _pointL & pt_rb )
+{
+ _pointL pt_lefttop_L, pt_rightbottom_L;
+ _pointD pt_lefttop_D, pt_rightbottom_D, pt_offset, pt_area;
+ marquee * cur_marq;
+
+ pt_lefttop_L = pt_lt;
+ pt_rightbottom_L = pt_rb;
+
+ check_ltrb ( & pt_lefttop_L, & pt_rightbottom_L );
+
+ pt_lefttop_D = clientpix2inches ( pt_lefttop_L );
+ pt_rightbottom_D = clientpix2inches ( pt_rightbottom_L );
+
+ pt_offset = pt_lefttop_D;
+ pt_area = pt_rightbottom_D - pt_lefttop_D;
+
+ check_max_size ( & pt_offset, & pt_area, 0 );
+
+ cur_marq = & g_view_manager->get_marquee ();
+
+ cur_marq->offset = pt_offset;
+ cur_marq->area = pt_area;
+
+ ::g_view_manager->sensitive ( );
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::begin_mouse_move ( _pointL * pt_lt, _pointL * pt_rb )
+{
+ switch ( m_cursor_state )
+ {
+ case PISA_CS_CROSS:
+ case PISA_CS_HAND:
+ break;
+ case PISA_CS_TOP:
+ pt_lt->x = pt_rb->x;
+ pt_rb->y = pt_lt->y;
+ break;
+ case PISA_CS_BOTTOM:
+ * pt_lt = * pt_rb;
+ break;
+ case PISA_CS_LEFT:
+ pt_lt->y = pt_rb->y;
+ pt_rb->x = pt_lt->x;
+ break;
+ case PISA_CS_RIGHT:
+ * pt_lt = * pt_rb;
+ break;
+ case PISA_CS_LEFTTOP:
+ * pt_rb = * pt_lt;
+ break;
+ case PISA_CS_LEFTBOTTOM:
+ pt_lt->y = pt_rb->y;
+ pt_rb->x = pt_lt->x;
+ break;
+ case PISA_CS_RIGHTBOTTOM:
+ * pt_lt = * pt_rb;
+ break;
+ case PISA_CS_RIGHTTOP:
+ pt_lt->x = pt_rb->x;
+ pt_rb->y = pt_lt->y;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::move_rect ( _pointL * pt_lt, _pointL * pt_rb,
+ const _pointL & pt_move )
+{
+ // move direction
+ typedef enum { DIR_LT, DIR_LB, DIR_RT, DIR_RB } MOVE_DIR;
+ MOVE_DIR direction;
+ _pointL pt_tmp, pt_tmp_move ( pt_move );
+ _pointL pt_size;
+ _pointD pt_lefttop_D, pt_rightbottom_D;
+ _pointL pt_lefttop_L, pt_rightbottom_L;
+
+ if ( pt_move.x < 0 )
+ {
+ if ( pt_move.y < 0 )
+ direction = DIR_LT;
+ else
+ direction = DIR_LB;
+ }
+ else
+ {
+ if ( pt_move.y < 0 )
+ direction = DIR_RT;
+ else
+ direction = DIR_RB;
+ }
+
+ pt_lefttop_D = m_pt_save_offset;
+ pt_rightbottom_D = m_pt_save_offset + m_pt_save_area;
+
+ pt_lefttop_L = inches2clientpix ( pt_lefttop_D );
+ pt_rightbottom_L = inches2clientpix ( pt_rightbottom_D );
+
+ pt_size.x = pt_rightbottom_L.x - pt_lefttop_L.x + 1;
+ pt_size.y = pt_rightbottom_L.y - pt_lefttop_L.y + 1;
+
+ switch ( direction )
+ {
+ case DIR_LT:
+ pt_tmp.x = pt_lt->x + pt_tmp_move.x;
+ if ( pt_tmp.x < m_pt_max_lt.x )
+ pt_tmp.x = m_pt_max_lt.x;
+ pt_tmp.y = pt_lt->y + pt_tmp_move.y;
+ if ( pt_tmp.y < m_pt_max_lt.y )
+ pt_tmp.y = m_pt_max_lt.y;
+ * pt_rb = pt_tmp + ( * pt_rb - * pt_lt );
+ * pt_lt = pt_tmp;
+ break;
+ case DIR_LB:
+ pt_tmp.x = pt_lt->x + pt_tmp_move.x;
+ if ( pt_tmp.x < m_pt_max_lt.x )
+ pt_tmp.x = m_pt_max_lt.x;
+ pt_tmp.y = pt_rb->y + pt_tmp_move.y;
+ if ( m_pt_max_rb.y < pt_tmp.y )
+ pt_tmp.y = m_pt_max_rb.y;
+ pt_lt->y = pt_tmp.y - ( pt_rb->y - pt_lt->y );
+ pt_rb->x = pt_tmp.x - ( pt_rb->x - pt_lt->x );
+ pt_lt->x = pt_tmp.x;
+ pt_rb->y = pt_tmp.y;
+ break;
+ case DIR_RT:
+ pt_tmp.x = pt_rb->x + pt_tmp_move.x;
+ if ( m_pt_max_rb.x < pt_tmp.x )
+ pt_tmp.x = m_pt_max_rb.x;
+ pt_tmp.y = pt_lt->y + pt_tmp_move.y;
+ if ( pt_tmp.y < m_pt_max_lt.y )
+ pt_tmp.y = m_pt_max_lt.y;
+ pt_lt->x = pt_tmp.x - ( pt_rb->x - pt_lt->x );
+ pt_rb->y = pt_tmp.y + ( pt_rb->y - pt_lt->y );
+ pt_lt->y = pt_tmp.y;
+ pt_rb->x = pt_tmp.x;
+ break;
+ case DIR_RB:
+ pt_tmp.x = pt_rb->x + pt_tmp_move.x;
+ if ( m_pt_max_rb.x < pt_tmp.x )
+ pt_tmp.x = m_pt_max_rb.x;
+ pt_tmp.y = pt_rb->y + pt_tmp_move.y;
+ if ( m_pt_max_rb.y < pt_tmp.y )
+ pt_tmp.y = m_pt_max_rb.y;
+ * pt_lt = pt_tmp - ( * pt_rb - * pt_lt );
+ * pt_rb = pt_tmp;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------*/
+_pointD preview_window::clientpix2inches ( _pointL & pt )
+{
+ _pointD pt_result;
+ _pointD pt_tmp;
+ double da, db;
+
+ da = m_client_rect.right - m_client_rect.left;
+ db = m_img_rect.right - m_img_rect.left;
+ pt_tmp.x = similarity ( ( double ) pt.x, da, db );
+
+ da = m_client_rect.bottom - m_client_rect.top;
+ db = m_img_rect.bottom - m_img_rect.top;
+ pt_tmp.y = similarity ( ( double ) pt.y, da, db );
+
+
+ pt_result.x = m_img_rect.left + pt_tmp.x;
+ pt_result.y = m_img_rect.top + pt_tmp.y;
+
+ return pt_result;
+}
+
+/*--------------------------------------------------------------*/
+_pointL preview_window::inches2clientpix ( _pointD & pt )
+{
+ _pointD pt_tmp;
+ _pointL pt_result;
+ double da, db;
+
+ pt_tmp.x = pt.x - m_img_rect.left;
+ pt_tmp.y = pt.y - m_img_rect.top;
+
+ da = m_img_rect.right - m_img_rect.left;
+ db = m_client_rect.right - m_client_rect.left;
+ pt_result.x = ( long ) similarity ( pt_tmp.x, da, db );
+
+ da = m_img_rect.bottom - m_img_rect.top;
+ db = m_client_rect.bottom - m_client_rect.top;
+ pt_result.y = ( long ) similarity ( pt_tmp.y, da, db );
+
+ return pt_result;
+}
+
+/*--------------------------------------------------------------*/
+int preview_window::get_marquee_point ( long i, _pointL * pt_lt, _pointL * pt_rb )
+{
+ marquee * marq;
+ _pointD pt_tmp_lt, pt_tmp_rb;
+
+ if (0 == (marq = & g_view_manager->get_marquee (i)))
+ return 0;
+
+ pt_tmp_lt = marq->offset;
+ pt_tmp_rb = marq->offset + marq->area;
+
+ * pt_lt = inches2clientpix ( pt_tmp_lt );
+ * pt_rb = inches2clientpix ( pt_tmp_rb );
+
+ return 1;
+}
+
+/*--------------------------------------------------------------*/
+int preview_window::check_min_size ( const _pointL & pt_lt, const _pointL & pt_rb )
+{
+ _pointD pt_zero_D, pt_min_D;
+ _pointL pt_min_L;
+
+ pt_zero_D.x = 0.0;
+ pt_zero_D.y = 0.0;
+ pt_min_D.x = g_min_marq_size;
+ pt_min_D.y = g_min_marq_size;
+ pt_min_L = inches2clientpix ( pt_min_D ) - inches2clientpix ( pt_zero_D );
+
+ if ( ::abs ( pt_lt.x - pt_rb.x ) < pt_min_L.x ||
+ ::abs ( pt_lt.y - pt_rb.y ) < pt_min_L.y )
+ return 0;
+ else
+ return 1;
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::check_max_size ( _pointD * pt_offset, _pointD * pt_area,
+ int offset )
+{
+ if ( pt_offset->x < 0.0 ) pt_offset->x = 0.0;
+ if ( pt_offset->y < 0.0 ) pt_offset->y = 0.0;
+
+ if ( pt_area->x > m_max_img_rect.right ) pt_area->x = m_max_img_rect.right;
+ if ( pt_area->y > m_max_img_rect.bottom ) pt_area->y = m_max_img_rect.bottom;
+
+ if ( offset )
+ {
+ if ( m_max_img_rect.right < pt_offset->x + pt_area->x )
+ pt_area->x = m_max_img_rect.right - pt_offset->x;
+ if ( m_max_img_rect.bottom < pt_offset->y + pt_area->y )
+ pt_area->y = m_max_img_rect.bottom - pt_offset->y;
+ }
+ else
+ {
+ if ( m_max_img_rect.right < pt_offset->x + pt_area->x )
+ pt_offset->x = m_max_img_rect.right - pt_area->x;
+ if ( m_max_img_rect.bottom < pt_offset->y + pt_area->y )
+ pt_offset->y = m_max_img_rect.bottom - pt_area->y;
+ }
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::check_ltrb ( _pointL * pt_lt, _pointL * pt_rb )
+{
+ _pointL pt_ret_lt, pt_ret_rb;
+
+ pt_ret_lt.x = ( pt_lt->x < pt_rb->x ) ? pt_lt->x : pt_rb->x;
+ pt_ret_lt.y = ( pt_lt->y < pt_rb->y ) ? pt_lt->y : pt_rb->y;
+ pt_ret_rb.x = ( pt_lt->x > pt_rb->x ) ? pt_lt->x : pt_rb->x;
+ pt_ret_rb.y = ( pt_lt->y > pt_rb->y ) ? pt_lt->y : pt_rb->y;
+
+ * pt_lt = pt_ret_lt;
+ * pt_rb = pt_ret_rb;
+}
+
+/*--------------------------------------------------------------*/
+void preview_window::draw_rect ( const _pointL & pt_lt,
+ const _pointL & pt_rb )
+{
+ int x, y, w, h;
+
+ if ( m_gc == 0 )
+ {
+ m_gc = ::gdk_gc_new ( m_prev->window );
+ ::gdk_gc_set_function ( m_gc, GDK_INVERT );
+ ::gdk_gc_set_line_attributes ( m_gc, 1, GDK_LINE_ON_OFF_DASH,
+ GDK_CAP_BUTT, GDK_JOIN_MITER );
+ }
+
+ x = ( pt_lt.x < pt_rb.x ) ? pt_lt.x : pt_rb.x;
+ y = ( pt_lt.y < pt_rb.y ) ? pt_lt.y : pt_rb.y;
+ w = ( pt_lt.x > pt_rb.x ) ? pt_lt.x - pt_rb.x : pt_rb.x - pt_lt.x;
+ h = ( pt_lt.y > pt_rb.y ) ? pt_lt.y - pt_rb.y : pt_rb.y - pt_lt.y;
+
+ ::gdk_draw_rectangle ( m_prev->window, m_gc, FALSE,
+ x, y, w, h );
+}
+
+