summaryrefslogtreecommitdiffstats
path: root/plug-ins/print/print-page-layout.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--plug-ins/print/print-page-layout.c948
1 files changed, 948 insertions, 0 deletions
diff --git a/plug-ins/print/print-page-layout.c b/plug-ins/print/print-page-layout.c
new file mode 100644
index 0000000..1fb91de
--- /dev/null
+++ b/plug-ins/print/print-page-layout.c
@@ -0,0 +1,948 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include "print.h"
+#include "print-page-layout.h"
+#include "print-preview.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+
+typedef struct
+{
+ PrintData *data;
+ gint image_width;
+ gint image_height;
+ GimpSizeEntry *size_entry;
+ GimpSizeEntry *resolution_entry;
+ GimpChainButton *chain;
+ GtkWidget *center_combo;
+ GtkWidget *area_label;
+ GtkWidget *preview;
+ GtkAdjustment *left_adj;
+ GtkAdjustment *right_adj;
+ GtkAdjustment *top_adj;
+ GtkAdjustment *bottom_adj;
+} PrintSizeInfo;
+
+enum
+{
+ BOTTOM,
+ TOP,
+ RIGHT,
+ LEFT,
+ WIDTH,
+ HEIGHT
+};
+
+
+static void print_page_setup_notify (GtkPrintOperation *operation);
+static void update_custom_widget (GtkPrintOperation *operation,
+ GtkWidget *custom_widget,
+ GtkPageSetup *page_setup,
+ GtkPrintSettings *print_settings);
+
+static GtkWidget * print_size_frame (PrintData *data,
+ GtkSizeGroup *label_group,
+ GtkSizeGroup *entry_group);
+static GtkWidget * print_offset_frame (PrintData *data,
+ GtkSizeGroup *label_group,
+ GtkSizeGroup *entry_group);
+
+static void print_size_info_update_offsets (void);
+static void print_size_info_size_changed (GtkWidget *widget);
+static void print_size_info_offset_max_changed (GtkAdjustment *adj,
+ gpointer data);
+static void print_size_info_resolution_changed (GtkWidget *widget);
+static void print_size_info_unit_changed (GtkWidget *widget);
+static void print_size_info_preview_offset_changed
+ (GtkWidget *widget,
+ gdouble offset_x,
+ gdouble offset_y);
+static void print_size_info_center_changed (GtkWidget *widget);
+static void print_size_info_center_none (void);
+static void print_size_info_use_full_page_toggled
+ (GtkWidget *widget);
+
+static void print_size_info_set_resolution (PrintSizeInfo *info,
+ gdouble xres,
+ gdouble yres);
+
+
+static void print_size_info_set_page_setup (PrintSizeInfo *info);
+
+static void print_draw_crop_marks_toggled (GtkWidget *widget);
+
+static void print_resolution_load_defaults (PrintSizeInfo *info);
+
+static PrintSizeInfo info;
+
+
+GtkWidget *
+print_page_layout_gui (PrintData *data,
+ const gchar *help_id)
+{
+ GtkWidget *main_hbox;
+ GtkWidget *main_vbox;
+ GtkWidget *button;
+ GtkWidget *frame;
+ GtkPageSetup *setup;
+ GtkSizeGroup *label_group;
+ GtkSizeGroup *entry_group;
+
+ memset (&info, 0, sizeof (PrintSizeInfo));
+
+ info.data = data;
+ info.image_width = gimp_drawable_width (data->drawable_id);
+ info.image_height = gimp_drawable_height (data->drawable_id);
+
+ setup = gtk_print_operation_get_default_page_setup (data->operation);
+ if (! setup)
+ {
+ setup = gtk_page_setup_new ();
+ gtk_print_operation_set_default_page_setup (data->operation, setup);
+ }
+
+ /* main hbox */
+ main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
+
+ /* main vbox */
+ main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_box_pack_start (GTK_BOX (main_hbox), main_vbox, FALSE, FALSE, 0);
+ gtk_widget_show (main_vbox);
+
+ label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ entry_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ /* size entry area for the image's print size */
+
+ frame = print_size_frame (data, label_group, entry_group);
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ /* offset entry area for the image's offset position */
+
+ frame = print_offset_frame (data, label_group, entry_group);
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ g_object_unref (label_group);
+ g_object_unref (entry_group);
+
+ button = gtk_check_button_new_with_mnemonic (_("Ignore Page _Margins"));
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ data->use_full_page);
+ gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "toggled",
+ G_CALLBACK (print_size_info_use_full_page_toggled),
+ NULL);
+ gtk_widget_show (button);
+
+ /* crop marks toggle */
+ button = gtk_check_button_new_with_mnemonic (_("_Draw Crop Marks"));
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ data->draw_crop_marks);
+ gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "toggled",
+ G_CALLBACK (print_draw_crop_marks_toggled),
+ NULL);
+ gtk_widget_show (button);
+
+ /* preview */
+ frame = gimp_frame_new (_("Preview"));
+ gtk_box_pack_start (GTK_BOX (main_hbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ info.preview = print_preview_new (setup, data->drawable_id);
+ print_preview_set_use_full_page (PRINT_PREVIEW (info.preview),
+ data->use_full_page);
+ gtk_container_add (GTK_CONTAINER (frame), info.preview);
+ gtk_widget_show (info.preview);
+
+ g_signal_connect (info.preview, "offsets-changed",
+ G_CALLBACK (print_size_info_preview_offset_changed),
+ NULL);
+
+ print_size_info_set_page_setup (&info);
+
+ g_signal_connect_object (data->operation, "notify::default-page-setup",
+ G_CALLBACK (print_page_setup_notify),
+ main_hbox, 0);
+ g_signal_connect_object (data->operation, "update-custom-widget",
+ G_CALLBACK (update_custom_widget),
+ main_hbox, 0);
+
+ gimp_help_connect (main_hbox, gimp_standard_help_func, help_id, NULL);
+
+ return main_hbox;
+}
+
+static void
+print_page_setup_notify (GtkPrintOperation *operation)
+{
+ GtkPageSetup *setup;
+
+ setup = gtk_print_operation_get_default_page_setup (operation);
+
+ print_size_info_set_page_setup (&info);
+ print_preview_set_page_setup (PRINT_PREVIEW (info.preview), setup);
+}
+
+static void
+update_custom_widget (GtkPrintOperation *operation,
+ GtkWidget *custom_widget,
+ GtkPageSetup *page_setup,
+ GtkPrintSettings *print_settings)
+{
+ gtk_print_operation_set_default_page_setup (operation, page_setup);
+}
+
+
+#define SB_WIDTH 8
+
+static GtkWidget *
+print_size_frame (PrintData *data,
+ GtkSizeGroup *label_group,
+ GtkSizeGroup *entry_group)
+{
+ GtkWidget *entry;
+ GtkWidget *height;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *chain;
+ GtkWidget *frame;
+ GtkWidget *label;
+ GtkWidget *button;
+ GtkAdjustment *adj;
+ gdouble image_width;
+ gdouble image_height;
+
+ image_width = (info.image_width *
+ gimp_unit_get_factor (data->unit) / data->xres);
+ image_height = (info.image_height *
+ gimp_unit_get_factor (data->unit) / data->yres);
+
+ frame = gimp_frame_new (_("Size"));
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ /* the print size entry */
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ entry = gimp_size_entry_new (1, data->unit, "%p",
+ FALSE, FALSE, FALSE, SB_WIDTH,
+ GIMP_SIZE_ENTRY_UPDATE_SIZE);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+ gtk_widget_show (entry);
+
+ info.size_entry = GIMP_SIZE_ENTRY (entry);
+
+ gtk_table_set_row_spacings (GTK_TABLE (entry), 2);
+ gtk_table_set_col_spacing (GTK_TABLE (entry), 0, 6);
+ gtk_table_set_col_spacing (GTK_TABLE (entry), 2, 6);
+
+ adj = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+ height = gimp_spin_button_new (adj, 1, 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (height), TRUE);
+ gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
+ GTK_SPIN_BUTTON (height), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (entry), height, 1, 2, 0, 1);
+ gtk_widget_show (height);
+
+ gtk_size_group_add_widget (entry_group, height);
+
+ gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry),
+ _("_Width:"), 0, 0, 0.0);
+ label = gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry),
+ _("_Height:"), 1, 0, 0.0);
+
+ gtk_size_group_add_widget (label_group, label);
+
+ gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), 0,
+ data->xres, FALSE);
+ gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), 1,
+ data->yres, FALSE);
+
+ gimp_size_entry_set_value (GIMP_SIZE_ENTRY (entry), 0, image_width);
+ gimp_size_entry_set_value (GIMP_SIZE_ENTRY (entry), 1, image_height);
+
+ /* the resolution entry */
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ entry = gimp_size_entry_new (1, data->image_unit,
+ _("pixels/%a"),
+ FALSE, FALSE, FALSE, SB_WIDTH,
+ GIMP_SIZE_ENTRY_UPDATE_RESOLUTION);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+ gtk_widget_show (entry);
+
+ info.resolution_entry = GIMP_SIZE_ENTRY (entry);
+
+ gtk_table_set_row_spacings (GTK_TABLE (entry), 2);
+ gtk_table_set_col_spacing (GTK_TABLE (entry), 0, 6);
+ gtk_table_set_col_spacing (GTK_TABLE (entry), 2, 6);
+
+ adj = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+ height = gimp_spin_button_new (adj, 1, 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (height), TRUE);
+ gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
+ GTK_SPIN_BUTTON (height), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (entry), height, 1, 2, 0, 1);
+ gtk_widget_show (height);
+
+ gtk_size_group_add_widget (entry_group, height);
+
+ label = gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry),
+ _("_X resolution:"), 0, 0, 0.0);
+ gtk_size_group_add_widget (label_group, label);
+
+ label = gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry),
+ _("_Y resolution:"), 1, 0, 0.0);
+ gtk_size_group_add_widget (label_group, label);
+
+ button = gtk_button_new_with_mnemonic (_("_Load Defaults"));
+ g_signal_connect_swapped (button, "clicked",
+ G_CALLBACK (print_resolution_load_defaults),
+ &info);
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (entry), 0,
+ GIMP_MIN_RESOLUTION,
+ GIMP_MAX_RESOLUTION);
+ gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (entry), 1,
+ GIMP_MIN_RESOLUTION,
+ GIMP_MAX_RESOLUTION);
+
+ gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (entry), 0, data->xres);
+ gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (entry), 1, data->yres);
+
+ chain = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
+ if (ABS (data->xres - data->yres) < GIMP_MIN_RESOLUTION)
+ gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chain), TRUE);
+ gtk_table_attach (GTK_TABLE (entry), chain, 2, 3, 0, 2,
+ GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (chain);
+
+ info.chain = GIMP_CHAIN_BUTTON (chain);
+
+ g_signal_connect (info.resolution_entry, "value-changed",
+ G_CALLBACK (print_size_info_resolution_changed),
+ NULL);
+ g_signal_connect (info.size_entry, "unit-changed",
+ G_CALLBACK (print_size_info_unit_changed),
+ NULL);
+
+ return frame;
+}
+
+static GtkWidget *
+print_offset_frame (PrintData *data,
+ GtkSizeGroup *label_group,
+ GtkSizeGroup *entry_group)
+{
+ GtkWidget *entry;
+ GtkWidget *spinner;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *frame;
+ GtkWidget *label;
+ GtkWidget *combo;
+
+ frame = gimp_frame_new (_("Position"));
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ /* the offset entry */
+
+ entry = GTK_WIDGET (info.size_entry);
+
+ table = gtk_table_new (4, 4, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacing (GTK_TABLE (table), 0, 0);
+ gtk_table_set_col_spacing (GTK_TABLE (table), 1, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ /* left */
+ info.left_adj = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+ spinner = gimp_spin_button_new (info.left_adj, 1, 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE);
+
+ gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
+ GTK_SPIN_BUTTON (spinner), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table), spinner, 1, 2, 0, 1);
+ gtk_widget_show (spinner);
+
+ label = gtk_label_new_with_mnemonic (_("_Left:"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinner);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
+ gtk_size_group_add_widget (label_group, label);
+ gtk_widget_show (label);
+
+ /* right */
+ info.right_adj = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+ spinner = gimp_spin_button_new (info.right_adj, 1, 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE);
+
+ g_signal_connect (info.right_adj, "value-changed",
+ G_CALLBACK (print_size_info_offset_max_changed),
+ GINT_TO_POINTER (LEFT));
+
+ gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
+ GTK_SPIN_BUTTON (spinner), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table), spinner, 3, 4, 0, 1);
+ gtk_widget_show (spinner);
+
+ label = gtk_label_new_with_mnemonic (_("_Right:"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinner);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 0, 1);
+ gtk_widget_show (label);
+
+ /* top */
+ info.top_adj = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+ spinner = gimp_spin_button_new (info.top_adj, 1, 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE);
+
+ gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
+ GTK_SPIN_BUTTON (spinner), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table), spinner, 1, 2, 1, 2);
+ gtk_widget_show (spinner);
+
+ label = gtk_label_new_with_mnemonic (_("_Top:"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinner);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+ gtk_size_group_add_widget (label_group, label);
+ gtk_widget_show (label);
+
+ /* bottom */
+ info.bottom_adj = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+ spinner = gimp_spin_button_new (info.bottom_adj, 1, 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE);
+
+ g_signal_connect (info.bottom_adj, "value-changed",
+ G_CALLBACK (print_size_info_offset_max_changed),
+ GINT_TO_POINTER (TOP));
+
+ gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
+ GTK_SPIN_BUTTON (spinner), NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table), spinner, 3, 4, 1, 2);
+ gtk_widget_show (spinner);
+
+ label = gtk_label_new_with_mnemonic (_("_Bottom:"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinner);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 1, 2);
+ gtk_widget_show (label);
+
+ gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), LEFT, 72.0, FALSE);
+ gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), RIGHT, 72.0, FALSE);
+ gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), TOP, 72.0, FALSE);
+ gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), BOTTOM, 72.0, FALSE);
+
+ print_size_info_update_offsets ();
+
+ g_signal_connect (info.size_entry, "value-changed",
+ G_CALLBACK (print_size_info_size_changed),
+ NULL);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new_with_mnemonic (_("C_enter:"));
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_size_group_add_widget (label_group, label);
+ gtk_widget_show (label);
+
+ /* if and how to center the image on the page */
+ combo = gimp_int_combo_box_new (C_("center-mode", "None"), CENTER_NONE,
+ _("Horizontally"), CENTER_HORIZONTALLY,
+ _("Vertically"), CENTER_VERTICALLY,
+ _("Both"), CENTER_BOTH,
+ NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
+ gtk_widget_show (combo);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+
+ gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
+ data->center,
+ G_CALLBACK (print_size_info_center_changed),
+ NULL);
+
+ info.center_combo = combo;
+
+ g_signal_connect (info.left_adj, "value-changed",
+ G_CALLBACK (print_size_info_center_none),
+ NULL);
+ g_signal_connect (info.right_adj, "value-changed",
+ G_CALLBACK (print_size_info_center_none),
+ NULL);
+ g_signal_connect (info.top_adj, "value-changed",
+ G_CALLBACK (print_size_info_center_none),
+ NULL);
+ g_signal_connect (info.bottom_adj, "value-changed",
+ G_CALLBACK (print_size_info_center_none),
+ NULL);
+
+ return frame;
+}
+
+static void
+print_size_info_get_page_dimensions (PrintSizeInfo *info,
+ gdouble *page_width,
+ gdouble *page_height,
+ GtkUnit unit)
+{
+ GtkPageSetup *setup;
+
+ setup = gtk_print_operation_get_default_page_setup (info->data->operation);
+
+ if (info->data->use_full_page)
+ {
+ *page_width = gtk_page_setup_get_paper_width (setup, unit);
+ *page_height = gtk_page_setup_get_paper_height (setup, unit);
+ }
+ else
+ {
+ *page_width = gtk_page_setup_get_page_width (setup, unit);
+ *page_height = gtk_page_setup_get_page_height (setup, unit);
+ }
+
+}
+
+static void
+gimp_size_info_get_max_offsets (gdouble *offset_x_max,
+ gdouble *offset_y_max)
+{
+ gdouble width;
+ gdouble height;
+
+ print_size_info_get_page_dimensions (&info, &width, &height, GTK_UNIT_POINTS);
+
+ *offset_x_max = width - 72.0 * info.image_width / info.data->xres;
+ *offset_x_max = MAX (0, *offset_x_max);
+
+ *offset_y_max = height - 72.0 * info.image_height / info.data->yres;
+ *offset_y_max = MAX (0, *offset_y_max);
+}
+
+static void
+print_size_info_center_none_block (void)
+{
+ g_signal_handlers_block_by_func (info.left_adj,
+ print_size_info_center_none, NULL);
+ g_signal_handlers_block_by_func (info.right_adj,
+ print_size_info_center_none, NULL);
+ g_signal_handlers_block_by_func (info.top_adj,
+ print_size_info_center_none, NULL);
+ g_signal_handlers_block_by_func (info.bottom_adj,
+ print_size_info_center_none, NULL);
+}
+
+static void
+print_size_info_center_none_unblock (void)
+{
+ g_signal_handlers_unblock_by_func (info.left_adj,
+ print_size_info_center_none, NULL);
+ g_signal_handlers_unblock_by_func (info.right_adj,
+ print_size_info_center_none, NULL);
+ g_signal_handlers_unblock_by_func (info.top_adj,
+ print_size_info_center_none, NULL);
+ g_signal_handlers_unblock_by_func (info.bottom_adj,
+ print_size_info_center_none, NULL);
+}
+
+static void
+print_size_info_update_offsets (void)
+{
+ PrintData *data = info.data;
+ gdouble offset_x_max;
+ gdouble offset_y_max;
+
+ gimp_size_info_get_max_offsets (&offset_x_max, &offset_y_max);
+
+ g_signal_handlers_block_by_func (info.size_entry,
+ print_size_info_size_changed, NULL);
+
+ print_size_info_center_none_block ();
+
+ gimp_size_entry_set_refval_boundaries (info.size_entry, LEFT,
+ 0, offset_x_max);
+ gimp_size_entry_set_refval_boundaries (info.size_entry, RIGHT,
+ 0, offset_x_max);
+ gimp_size_entry_set_refval_boundaries (info.size_entry, TOP,
+ 0, offset_y_max);
+ gimp_size_entry_set_refval_boundaries (info.size_entry, BOTTOM,
+ 0, offset_y_max);
+
+ switch (data->center)
+ {
+ case CENTER_NONE:
+ break;
+
+ case CENTER_HORIZONTALLY:
+ data->offset_x = offset_x_max / 2.0;
+ break;
+
+ case CENTER_VERTICALLY:
+ data->offset_y = offset_y_max / 2.0;
+ break;
+
+ case CENTER_BOTH:
+ data->offset_x = offset_x_max / 2.0;
+ data->offset_y = offset_y_max / 2.0;
+ break;
+ }
+
+ gimp_size_entry_set_refval (info.size_entry, LEFT,
+ data->offset_x);
+ gimp_size_entry_set_refval (info.size_entry, RIGHT,
+ offset_x_max - data->offset_x);
+ gimp_size_entry_set_refval (info.size_entry, TOP,
+ info.data->offset_y);
+ gimp_size_entry_set_refval (info.size_entry, BOTTOM,
+ offset_y_max - data->offset_y);
+
+ print_size_info_center_none_unblock ();
+
+ g_signal_handlers_unblock_by_func (info.size_entry,
+ print_size_info_size_changed, NULL);
+}
+
+static void
+print_size_info_center_changed (GtkWidget *combo)
+{
+ gint value;
+
+ if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (combo), &value))
+ {
+ info.data->center = value;
+
+ print_size_info_update_offsets ();
+
+ if (info.preview)
+ print_preview_set_image_offsets (PRINT_PREVIEW (info.preview),
+ info.data->offset_x,
+ info.data->offset_y);
+ }
+}
+
+static void
+print_size_info_center_none (void)
+{
+ /* return early if we are called from a unit change */
+ if (gimp_size_entry_get_unit (info.size_entry) != info.data->unit)
+ return;
+
+ info.data->center = CENTER_NONE;
+
+ if (info.center_combo)
+ {
+ g_signal_handlers_block_by_func (info.center_combo,
+ print_size_info_center_changed, NULL);
+
+ info.data->center = CENTER_NONE;
+
+ gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (info.center_combo),
+ info.data->center);
+
+ g_signal_handlers_unblock_by_func (info.center_combo,
+ print_size_info_center_changed, NULL);
+ }
+}
+
+static void
+print_size_info_preview_offset_changed (GtkWidget *widget,
+ gdouble offset_x,
+ gdouble offset_y)
+{
+ print_size_info_center_none ();
+
+ info.data->offset_x = offset_x;
+ info.data->offset_y = offset_y;
+
+ print_size_info_update_offsets ();
+}
+
+static void
+print_size_info_size_changed (GtkWidget *widget)
+{
+ gdouble width;
+ gdouble height;
+ gdouble xres;
+ gdouble yres;
+ gdouble scale;
+
+ scale = gimp_unit_get_factor (gimp_size_entry_get_unit (info.size_entry));
+
+ width = gimp_size_entry_get_value (info.size_entry, WIDTH);
+ height = gimp_size_entry_get_value (info.size_entry, HEIGHT);
+
+ xres = scale * info.image_width / MAX (0.0001, width);
+ yres = scale * info.image_height / MAX (0.0001, height);
+
+ print_size_info_set_resolution (&info, xres, yres);
+
+ info.data->offset_x = gimp_size_entry_get_refval (info.size_entry, LEFT);
+ info.data->offset_y = gimp_size_entry_get_refval (info.size_entry, TOP);
+
+ print_preview_set_image_offsets (PRINT_PREVIEW (info.preview),
+ info.data->offset_x,
+ info.data->offset_y);
+}
+
+static void
+print_size_info_offset_max_changed (GtkAdjustment *adj,
+ gpointer data)
+{
+ guint index = GPOINTER_TO_INT (data);
+
+ /* return early if we are called from a unit change */
+ if (gimp_size_entry_get_unit (info.size_entry) != info.data->unit)
+ return;
+
+ g_signal_handlers_block_by_func (info.size_entry,
+ print_size_info_size_changed, NULL);
+
+ gimp_size_entry_set_value (info.size_entry, index,
+ gtk_adjustment_get_upper (adj) -
+ gtk_adjustment_get_value (adj));
+
+ g_signal_handlers_unblock_by_func (info.size_entry,
+ print_size_info_size_changed, NULL);
+}
+
+static void
+print_size_info_resolution_changed (GtkWidget *widget)
+{
+ GimpSizeEntry *entry = info.resolution_entry;
+ gdouble xres = gimp_size_entry_get_refval (entry, 0);
+ gdouble yres = gimp_size_entry_get_refval (entry, 1);
+
+ print_size_info_set_resolution (&info, xres, yres);
+}
+
+static void
+print_size_info_use_full_page_toggled (GtkWidget *widget)
+{
+ gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ info.data->use_full_page = active;
+
+ print_size_info_set_page_setup (&info);
+
+ print_preview_set_use_full_page (PRINT_PREVIEW(info.preview), active);
+}
+
+static void
+print_size_info_unit_changed (GtkWidget *widget)
+{
+ info.data->unit = gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (widget));
+
+ print_size_info_set_page_setup (&info);
+}
+
+static void
+print_size_info_set_resolution (PrintSizeInfo *info,
+ gdouble xres,
+ gdouble yres)
+{
+ PrintData *data = info->data;
+ gdouble offset_x;
+ gdouble offset_y;
+ gdouble offset_x_max;
+ gdouble offset_y_max;
+
+ if (info->chain && gimp_chain_button_get_active (info->chain))
+ {
+ if (xres != data->xres)
+ yres = xres;
+ else
+ xres = yres;
+ }
+
+ data->xres = xres;
+ data->yres = yres;
+
+ g_signal_handlers_block_by_func (info->resolution_entry,
+ print_size_info_resolution_changed,
+ NULL);
+
+ gimp_size_entry_set_refval (info->resolution_entry, 0, xres);
+ gimp_size_entry_set_refval (info->resolution_entry, 1, yres);
+
+ g_signal_handlers_unblock_by_func (info->resolution_entry,
+ print_size_info_resolution_changed,
+ NULL);
+
+ g_signal_handlers_block_by_func (info->size_entry,
+ print_size_info_size_changed,
+ NULL);
+
+ gimp_size_entry_set_value (info->size_entry, WIDTH,
+ info->image_width *
+ gimp_unit_get_factor (data->unit) / xres);
+ gimp_size_entry_set_value (info->size_entry, HEIGHT,
+ info->image_height *
+ gimp_unit_get_factor (data->unit) / yres);
+
+ g_signal_handlers_unblock_by_func (info->size_entry,
+ print_size_info_size_changed,
+ NULL);
+
+ gimp_size_info_get_max_offsets (&offset_x_max, &offset_y_max);
+
+ offset_x = gimp_size_entry_get_refval (info->size_entry, LEFT);
+ offset_y = gimp_size_entry_get_refval (info->size_entry, TOP);
+
+ offset_x = CLAMP (offset_x, 0, offset_x_max);
+ offset_y = CLAMP (offset_y, 0, offset_y_max);
+
+ data->offset_x = offset_x;
+ data->offset_y = offset_y;
+
+ print_size_info_update_offsets ();
+
+ print_preview_set_image_dpi (PRINT_PREVIEW (info->preview),
+ data->xres, data->yres);
+ print_preview_set_image_offsets (PRINT_PREVIEW (info->preview),
+ data->offset_x, data->offset_y);
+ print_preview_set_image_offsets_max (PRINT_PREVIEW (info->preview),
+ offset_x_max, offset_y_max);
+}
+
+static void
+print_size_info_set_page_setup (PrintSizeInfo *info)
+{
+ PrintData *data = info->data;
+ gdouble page_width;
+ gdouble page_height;
+ gdouble x;
+ gdouble y;
+
+ print_size_info_get_page_dimensions (info,
+ &page_width, &page_height,
+ GTK_UNIT_INCH);
+
+ page_width *= gimp_unit_get_factor (data->unit);
+ page_height *= gimp_unit_get_factor (data->unit);
+
+ if (info->area_label)
+ {
+ gchar *format;
+ gchar *text;
+
+ format = g_strdup_printf ("%%.%df x %%.%df %s",
+ gimp_unit_get_digits (data->unit),
+ gimp_unit_get_digits (data->unit),
+ gimp_unit_get_plural (data->unit));
+ text = g_strdup_printf (format, page_width, page_height);
+ g_free (format);
+
+ gtk_label_set_text (GTK_LABEL (info->area_label), text);
+ g_free (text);
+ }
+
+ x = page_width;
+ y = page_height;
+
+ if (info->chain && gimp_chain_button_get_active (info->chain))
+ {
+ gdouble ratio_x = page_width / (gdouble) info->image_width;
+ gdouble ratio_y = page_height / (gdouble) info->image_height;
+
+ if (ratio_x < ratio_y)
+ y = (gdouble) info->image_height * ratio_x;
+ else
+ x = (gdouble) info->image_width * ratio_y;
+ }
+
+ gimp_size_entry_set_value_boundaries (info->size_entry, WIDTH,
+ page_width / 100.0, x);
+ gimp_size_entry_set_value_boundaries (info->size_entry, HEIGHT,
+ page_height / 100.0, y);
+
+ print_size_info_get_page_dimensions (info,
+ &page_width, &page_height,
+ GTK_UNIT_POINTS);
+
+ x = (gdouble) info->image_width / page_width * 72.0;
+ y = (gdouble) info->image_height / page_height * 72.0;
+
+ if (info->chain && gimp_chain_button_get_active (info->chain))
+ {
+ gdouble max = MAX (x, y);
+
+ x = y = max;
+ }
+
+ data->min_xres = x;
+ data->min_yres = y;
+ gimp_size_entry_set_refval_boundaries (info->resolution_entry, 0,
+ x, GIMP_MAX_RESOLUTION);
+ gimp_size_entry_set_refval_boundaries (info->resolution_entry, 1,
+ y, GIMP_MAX_RESOLUTION);
+}
+
+static void
+print_draw_crop_marks_toggled (GtkWidget *widget)
+{
+ gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ info.data->draw_crop_marks = active;
+}
+
+static void
+print_resolution_load_defaults (PrintSizeInfo *info)
+{
+ gdouble xres;
+ gdouble yres;
+
+ gimp_image_get_resolution (info->data->image_id, &xres, &yres);
+
+ gimp_size_entry_set_refval (info->resolution_entry, 0, xres);
+ gimp_size_entry_set_refval (info->resolution_entry, 1, yres);
+ print_size_info_resolution_changed (GTK_WIDGET (info->resolution_entry));
+}