gnome-scan r814 - in trunk: . modules/gsane
- From: bersace svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-scan r814 - in trunk: . modules/gsane
- Date: Sun, 1 Feb 2009 18:15:32 +0000 (UTC)
Author: bersace
Date: Sun Feb 1 18:15:32 2009
New Revision: 814
URL: http://svn.gnome.org/viewvc/gnome-scan?rev=814&view=rev
Log:
Support pixel defined scan area
Modified:
trunk/ChangeLog
trunk/modules/gsane/gsane-option-area.c
Modified: trunk/modules/gsane/gsane-option-area.c
==============================================================================
--- trunk/modules/gsane/gsane-option-area.c (original)
+++ trunk/modules/gsane/gsane-option-area.c Sun Feb 1 18:15:32 2009
@@ -37,6 +37,10 @@
GnomeScanOption* origin;
GnomeScanOption* paper_size;
GnomeScanOption* page_orientation;
+ GnomeScanUnit unit;
+ gdouble fake_resolution;
+ gdouble width;
+ gdouble height;
};
G_DEFINE_TYPE(GSaneOptionArea, gsane_option_area, GSANE_TYPE_OPTION_HANDLER)
@@ -45,10 +49,19 @@
gsane_option_area_install_origin(GSaneOptionArea *self)
{
GSaneOptionHandler* handler = (GSaneOptionHandler*) self;
- /* TODO: convert from non MM unit */
+ gdouble x, y;
+
+ x = gsane_option_handler_get_double(handler, self->priv->tl_x_desc, self->priv->tl_x_index, NULL);
+ y = gsane_option_handler_get_double(handler, self->priv->tl_y_desc, self->priv->tl_y_index, NULL);
+
+ if (self->priv->fake_resolution) {
+ x = gnome_scan_convert_to_mm(x, self->priv->unit, self->priv->fake_resolution);
+ y = gnome_scan_convert_to_mm(y, self->priv->unit, self->priv->fake_resolution);
+ }
+
GnomeScanPoint point = {
- .x = gsane_option_handler_get_double(handler, self->priv->tl_x_desc, self->priv->tl_x_index, NULL),
- .y = gsane_option_handler_get_double(handler, self->priv->tl_y_desc, self->priv->tl_y_index, NULL)
+ .x = x,
+ .y = y,
};
self->priv->origin = GNOME_SCAN_OPTION(gnome_scan_option_pointer_new("origin", _("Origin"), _("Coordinate of the top left corner of the paper."), GNOME_SCAN_OPTION_GROUP_FORMAT, GETTEXT_PACKAGE,
@@ -84,9 +97,17 @@
br_y = origin->y + gtk_paper_size_get_width(ps, GTK_UNIT_MM);
}
- g_debug("Scan (%.2f ; %.2f) (%.2f ; %.2f)", tl_x, tl_y, br_x, br_y);
+ g_debug("Scan (%.2f ; %.2f) (%.2f ; %.2f) mm", tl_x, tl_y, br_x, br_y);
+ if (self->priv->fake_resolution) {
+ tl_x = gnome_scan_convert_from_mm(tl_x, self->priv->unit, self->priv->fake_resolution);
+ tl_y = gnome_scan_convert_from_mm(tl_y, self->priv->unit, self->priv->fake_resolution);
+ br_x = gnome_scan_convert_from_mm(br_x, self->priv->unit, self->priv->fake_resolution);
+ br_y = gnome_scan_convert_from_mm(br_y, self->priv->unit, self->priv->fake_resolution);
+ g_debug("=> actual scan (%.2f ; %.2f) (%.2f ; %.2f) %s",
+ tl_x, tl_y, br_x, br_y,
+ gnome_scan_unit_to_string(self->priv->unit));
+ }
- /* TODO: convert to non MM unit */
gsane_option_handler_set_double(handler, self->priv->tl_x_desc, self->priv->tl_x_index, tl_x, NULL);
gsane_option_handler_set_double(handler, self->priv->tl_y_desc, self->priv->tl_y_index, tl_y, NULL);
gsane_option_handler_set_double(handler, self->priv->br_x_desc, self->priv->br_x_index, br_x, NULL);
@@ -100,31 +121,38 @@
}
static GSList*
-gsane_option_area_add_paper_size(GSaneOptionArea* self, GSList* values, const gchar* paper_name, gdouble width, gdouble height, GtkUnit unit)
+gsane_option_area_add_paper_size(GSaneOptionArea* self, GSList* values, const gchar* paper_name, gdouble width, gdouble height)
{
GtkPaperSize* ps;
- GnomeScanEnumValue evalue;
- GValue* value;
ps = gtk_paper_size_new(paper_name);
- if (gtk_paper_size_get_width(ps, unit) > width
- || gtk_paper_size_get_height(ps, unit) > height) {
- g_message("%s can't scan %s document, too wide for hardware extent.",
- gnome_scan_scanner_get_name(GSANE_OPTION_HANDLER(self)->scanner),
+ if (gtk_paper_size_get_width(ps, GTK_UNIT_MM) > width
+ || gtk_paper_size_get_height(ps, GTK_UNIT_MM) > height) {
+ g_message("Can't scan %s document, too wide for hardware extent.",
gtk_paper_size_get_display_name(ps));
gtk_paper_size_free(ps);
return values;
}
- value = g_new0(GValue, 1);
- g_value_init(value, GTK_TYPE_PAPER_SIZE);
- g_value_set_boxed(value, ps);
- gnome_scan_enum_value_init(&evalue, value, gtk_paper_size_get_display_name(ps), NULL);
- values = g_slist_append(values, gnome_scan_enum_value_dup(&evalue));
- gnome_scan_enum_value_destroy(&evalue);
- g_value_reset(value);
- g_free(value);
+ return g_slist_append(values, ps);
+}
+
+/* List common paper sizes. This will be extendable through
+ Preselection */
+static GSList*
+gsane_option_area_list_paper_sizes(GSaneOptionArea *self)
+{
+ GSList *values = NULL;
+
+ /* ISO format */
+ values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_A4, self->priv->width, self->priv->height);
+ values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_A5, self->priv->width, self->priv->height);
+
+ /* US bullshit non standard paper sizes */
+ values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_LETTER, self->priv->width, self->priv->height);
+ values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_LEGAL, self->priv->width, self->priv->height);
+ values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_EXECUTIVE, self->priv->width, self->priv->height);
return values;
}
@@ -133,73 +161,77 @@
gsane_option_area_install_paper_size(GSaneOptionArea* self)
{
GSaneOptionHandler* handler = (GSaneOptionHandler*)self;
- GtkPaperSize* ps;
- GnomeScanEnumValue evalue;
- GValue* value;
- GSList *values = NULL, *it;
- gdouble width, height;
- GnomeScanUnit unit = gsane_option_unit(self->priv->tl_x_desc);
+ GSList *ps_list = NULL, *it;
+ gdouble tlx, tly, brx, bry, width, height;
- /* get width and height */
- switch (self->priv->tl_x_desc->type) {
- case SANE_TYPE_INT:
- width = self->priv->br_x_desc->constraint.range->max;
- height = self->priv->br_y_desc->constraint.range->max;
- break;
- case SANE_TYPE_FIXED:
- width = SANE_UNFIX(self->priv->br_x_desc->constraint.range->max);
- height = SANE_UNFIX(self->priv->br_y_desc->constraint.range->max);
- break;
- default:
- g_warning("Unsupported coordinate type.");
- return;
- break;
+ tlx = gsane_option_handler_get_double(handler, self->priv->tl_x_desc, self->priv->tl_x_index, NULL);
+ tly = gsane_option_handler_get_double(handler, self->priv->tl_y_desc, self->priv->tl_y_index, NULL);
+ brx = gsane_option_handler_get_double(handler, self->priv->br_x_desc, self->priv->br_x_index, NULL);
+ bry = gsane_option_handler_get_double(handler, self->priv->br_y_desc, self->priv->br_y_index, NULL);
+ width = brx - tlx;
+ height = bry - tly;
+
+ /* We don't list paper size when using fake resolution because
+ we can't reliabily check whether fit the scan area. Also,
+ this will lead the ROI not to fit the actual paper on the
+ preview. Last but not least, pixel device are often webcam
+ and such device that really don't care paper sizes.
+ */
+ if (self->priv->fake_resolution) {
+ width = gnome_scan_convert_to_mm(width, self->priv->unit, self->priv->fake_resolution);
+ height = gnome_scan_convert_to_mm(height, self->priv->unit, self->priv->fake_resolution);
}
+ else
+ ps_list = gsane_option_area_list_paper_sizes(self);
- g_debug("%s extent is %.2fx%.2f %s",
- gnome_scan_scanner_get_name(handler->scanner),
- width, height, gnome_scan_unit_to_string(unit));
+ /* define special paper sizes */
- /* define max paper size */
- value = g_new0(GValue, 1);
- g_value_init(value, GTK_TYPE_PAPER_SIZE);
- ps = gtk_paper_size_new_custom("max", _("Maximum"), width, height, unit);
- g_value_set_boxed(value, ps);
- gnome_scan_enum_value_init(&evalue, value, gtk_paper_size_get_display_name(ps), NULL);
- values = g_slist_append(values, gnome_scan_enum_value_dup(&evalue));
- gnome_scan_enum_value_destroy(&evalue);
-
- /* A4 */
- values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_A4, width, height, unit);
- /* A5 */
- values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_A5, width, height, unit);
- /* US bullshit */
- values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_LETTER, width, height, unit);
- values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_LEGAL, width, height, unit);
- values = gsane_option_area_add_paper_size(self, values, GTK_PAPER_NAME_EXECUTIVE, width, height, unit);
+
+ ps_list = g_slist_prepend(ps_list,
+ /* Translator: manual selection display label */
+ gtk_paper_size_new_custom("manual", _("Manual"),
+ width, height,
+ GTK_UNIT_MM));
+
+ ps_list = g_slist_prepend(ps_list,
+ /* Translator: maximum paper size display label */
+ gtk_paper_size_new_custom("max", _("Maximum"),
+ self->priv->width, self->priv->height,
+ GTK_UNIT_MM));
+ GSList *enum_values = NULL;
+ GnomeScanEnumValue evalue;
+ GValue *value = g_new0(GValue,1);
gchar *papersizes = NULL, *old;
- const gchar* label;
- for(it = values; it; it = it->next) {
- label = ((GnomeScanEnumValue*)(it->data))->label;
+ g_value_init(value, GTK_TYPE_PAPER_SIZE);
+ for(it = ps_list; it; it = it->next) {
+ g_value_set_boxed(value, it->data);
+ gnome_scan_enum_value_init(&evalue, value, gtk_paper_size_get_display_name(it->data), NULL);
+ enum_values = g_slist_append(enum_values, gnome_scan_enum_value_dup(&evalue));
+
+ /* Assemble debugging list */
if (papersizes) {
old = papersizes;
- papersizes = g_strdup_printf("%s, \"%s\"", papersizes, label);
+ papersizes = g_strdup_printf("%s, \"%s\"", papersizes, evalue.label);
g_free(old);
}
else
- papersizes = g_strdup_printf("\"%s\"", label);
- }
+ papersizes = g_strdup_printf("\"%s\"", evalue.label);
+ gnome_scan_enum_value_destroy(&evalue);
+ }
g_value_reset(value);
g_free(value);
+
self->priv->paper_size = GNOME_SCAN_OPTION(gnome_scan_option_enum_new("paper-size", _("Paper-Size"), _("Paper-Size"), GNOME_SCAN_OPTION_GROUP_FORMAT, GETTEXT_PACKAGE,
- values->data, values, GNOME_SCAN_OPTION_HINT_PRIMARY));
+ enum_values->data, enum_values, GNOME_SCAN_OPTION_HINT_PRIMARY));
gnome_scan_node_install_option(GNOME_SCAN_NODE(handler->scanner), self->priv->paper_size);
g_signal_connect_swapped(self->priv->paper_size, "notify::value", G_CALLBACK(gsane_option_area_option_changed), self);
- g_debug("\toption : paper-size = \"%s\", enum = {%s}", ((GnomeScanEnumValue*)(values->data))->label, papersizes);
+ g_debug("\toption : paper-size = \"%s\", enum = {%s}", ((GnomeScanEnumValue*)(enum_values->data))->label, papersizes);
+ g_slist_foreach(ps_list, (GFunc) gtk_paper_size_free, NULL);
+ g_slist_free(ps_list);
g_free(papersizes);
}
@@ -245,6 +277,39 @@
g_signal_connect_swapped(self->priv->page_orientation, "notify::value", G_CALLBACK(gsane_option_area_option_changed), self);
}
+static gboolean
+gsane_option_area_get_extent(GSaneOptionArea *self, gdouble *width, gdouble *height)
+{
+ gdouble min, max;
+
+ /* TODO: handle enum ? Didn't found a backend using enum
+ constraint */
+ switch (self->priv->tl_x_desc->type) {
+ case SANE_TYPE_INT:
+ min = self->priv->br_x_desc->constraint.range->min;
+ max = self->priv->br_x_desc->constraint.range->max;
+ *width = max - min;
+ min = self->priv->br_y_desc->constraint.range->min;
+ max = self->priv->br_y_desc->constraint.range->max;
+ *height = max - min;
+ break;
+ case SANE_TYPE_FIXED:
+ min = SANE_UNFIX(self->priv->br_x_desc->constraint.range->min);
+ max = SANE_UNFIX(self->priv->br_x_desc->constraint.range->max);
+ *width = max - min;
+ min = SANE_UNFIX(self->priv->br_y_desc->constraint.range->min);
+ max = SANE_UNFIX(self->priv->br_y_desc->constraint.range->max);
+ *height = max - min;
+ break;
+ default:
+ g_warning("Unsupported coordinate unit.");
+ return FALSE;
+ break;
+ }
+
+ return TRUE;
+}
+
static void
gsane_option_handler_handle_matched(GSaneOptionHandler *handler, const SANE_Option_Descriptor* desc, SANE_Int n, const gchar*group)
{
@@ -255,7 +320,32 @@
if (self->priv->count < 4)
return;
- /* we have matched all SANE option, actually install high level options */
+ /* Here we have matched all SANE option we wanted */
+
+ if (!gsane_option_area_get_extent(self, &self->priv->width, &self->priv->height))
+ return;
+
+ self->priv->unit = gsane_option_unit(self->priv->tl_x_desc);
+ if (self->priv->unit == GNOME_SCAN_UNIT_PIXEL) {
+ /* Pixel defined area prevent us to get the actual
+ scanner extent. We assume the scanner can scan a US
+ Legal-width paper. We compute a fake resolution
+ based on this assumption. */
+ self->priv->fake_resolution = self->priv->width / (216. / 25.4);
+
+ self->priv->width = gnome_scan_convert_to_mm(self->priv->width,
+ self->priv->unit,
+ self->priv->fake_resolution);
+ self->priv->height = gnome_scan_convert_to_mm(self->priv->height,
+ self->priv->unit,
+ self->priv->fake_resolution);
+ }
+
+ g_debug("%s extent is %.2fx%.2f %s",
+ gnome_scan_scanner_get_name(handler->scanner),
+ self->priv->width, self->priv->height, gnome_scan_unit_to_string(self->priv->unit));
+
+ /* Actually install high level options */
gsane_option_area_install_origin(self);
gsane_option_area_install_paper_size(self);
gsane_option_area_install_page_orientation(self);
@@ -303,6 +393,5 @@
{
self->priv = GSANE_OPTION_AREA_GET_PRIVATE(self);
self->priv->count = 0;
+ self->priv->fake_resolution = 0.;
}
-
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]