/* Eye of Mate - Print Operations * * Copyright (C) 2005-2008 The Free Software Foundation * * Author: Claudio Saavedra <csaavedra@gnome.org> * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include <gtk/gtk.h> #include <glib/gi18n.h> #include "eom-image.h" #include "eom-print.h" #include "eom-print-image-setup.h" #include "eom-util.h" #include "eom-debug.h" #ifdef HAVE_RSVG #include <librsvg/rsvg-cairo.h> #endif #define EOM_PRINT_SETTINGS_FILE "eom-print-settings.ini" #define EOM_PAGE_SETUP_GROUP "Page Setup" #define EOM_PRINT_SETTINGS_GROUP "Print Settings" typedef struct { EomImage *image; gdouble left_margin; gdouble top_margin; gdouble scale_factor; GtkUnit unit; } EomPrintData; static void eom_print_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { cairo_t *cr; gdouble dpi_x, dpi_y; gdouble x0, y0; gdouble scale_factor; gdouble p_width, p_height; gint width, height; EomPrintData *data; GtkPageSetup *page_setup; eom_debug (DEBUG_PRINTING); data = (EomPrintData *) user_data; scale_factor = data->scale_factor/100; dpi_x = gtk_print_context_get_dpi_x (context); dpi_y = gtk_print_context_get_dpi_y (context); switch (data->unit) { case GTK_UNIT_INCH: x0 = data->left_margin * dpi_x; y0 = data->top_margin * dpi_y; break; case GTK_UNIT_MM: x0 = data->left_margin * dpi_x/25.4; y0 = data->top_margin * dpi_y/25.4; break; default: g_assert_not_reached (); } cr = gtk_print_context_get_cairo_context (context); cairo_translate (cr, x0, y0); page_setup = gtk_print_context_get_page_setup (context); p_width = gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS); p_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS); eom_image_get_size (data->image, &width, &height); /* this is both a workaround for a bug in cairo's PDF backend, and a way to ensure we are not printing outside the page margins */ cairo_rectangle (cr, 0, 0, MIN (width*scale_factor, p_width), MIN (height*scale_factor, p_height)); cairo_clip (cr); cairo_scale (cr, scale_factor, scale_factor); #ifdef HAVE_RSVG if (eom_image_is_svg (data->image)) { RsvgHandle *svg = eom_image_get_svg (data->image); rsvg_handle_render_cairo (svg, cr); } else #endif { GdkPixbuf *pixbuf; pixbuf = eom_image_get_pixbuf (data->image); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); g_object_unref (pixbuf); } } static GObject * eom_print_create_custom_widget (GtkPrintOperation *operation, gpointer user_data) { GtkPageSetup *page_setup; EomPrintData *data; eom_debug (DEBUG_PRINTING); data = (EomPrintData *)user_data; page_setup = gtk_print_operation_get_default_page_setup (operation); if (page_setup == NULL) page_setup = gtk_page_setup_new (); return G_OBJECT (eom_print_image_setup_new (data->image, page_setup)); } static void eom_print_custom_widget_apply (GtkPrintOperation *operation, GtkWidget *widget, gpointer user_data) { EomPrintData *data; gdouble left_margin, top_margin, scale_factor; GtkUnit unit; eom_debug (DEBUG_PRINTING); data = (EomPrintData *)user_data; eom_print_image_setup_get_options (EOM_PRINT_IMAGE_SETUP (widget), &left_margin, &top_margin, &scale_factor, &unit); data->left_margin = left_margin; data->top_margin = top_margin; data->scale_factor = scale_factor; data->unit = unit; } static void eom_print_end_print (GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data) { EomPrintData *data = (EomPrintData*) user_data; eom_debug (DEBUG_PRINTING); g_object_unref (data->image); g_slice_free (EomPrintData, data); } GtkPrintOperation * eom_print_operation_new (EomImage *image, GtkPrintSettings *print_settings, GtkPageSetup *page_setup) { GtkPrintOperation *print; EomPrintData *data; eom_debug (DEBUG_PRINTING); print = gtk_print_operation_new (); data = g_slice_new0 (EomPrintData); data->left_margin = 0; data->top_margin = 0; data->scale_factor = 100; data->image = g_object_ref (image); data->unit = GTK_UNIT_INCH; gtk_print_operation_set_print_settings (print, print_settings); gtk_print_operation_set_default_page_setup (print, page_setup); gtk_print_operation_set_n_pages (print, 1); gtk_print_operation_set_job_name (print, eom_image_get_caption (image)); gtk_print_operation_set_embed_page_setup (print, TRUE); g_signal_connect (print, "draw_page", G_CALLBACK (eom_print_draw_page), data); g_signal_connect (print, "create-custom-widget", G_CALLBACK (eom_print_create_custom_widget), data); g_signal_connect (print, "custom-widget-apply", G_CALLBACK (eom_print_custom_widget_apply), data); g_signal_connect (print, "end-print", G_CALLBACK (eom_print_end_print), data); g_signal_connect (print, "update-custom-widget", G_CALLBACK (eom_print_image_setup_update), data); gtk_print_operation_set_custom_tab_label (print, _("Image Settings")); return print; } static GKeyFile * eom_print_get_key_file (void) { GKeyFile *key_file; GError *error = NULL; gchar *filename; GFile *file; const gchar *dot_dir = eom_util_dot_dir (); filename = g_build_filename (dot_dir, EOM_PRINT_SETTINGS_FILE, NULL); file = g_file_new_for_path (filename); key_file = g_key_file_new (); if (g_file_query_exists (file, NULL)) { g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error); if (error) { g_warning ("Error loading print settings file: %s", error->message); g_error_free (error); g_object_unref (file); g_free (filename); g_key_file_free (key_file); return NULL; } } g_object_unref (file); g_free (filename); return key_file; } GtkPageSetup * eom_print_get_page_setup (void) { GtkPageSetup *page_setup; GKeyFile *key_file; GError *error = NULL; key_file = eom_print_get_key_file (); if (key_file && g_key_file_has_group (key_file, EOM_PAGE_SETUP_GROUP)) { page_setup = gtk_page_setup_new_from_key_file (key_file, EOM_PAGE_SETUP_GROUP, &error); } else { page_setup = gtk_page_setup_new (); } if (error) { page_setup = gtk_page_setup_new (); g_warning ("Error loading print settings file: %s", error->message); g_error_free (error); } if (key_file) g_key_file_free (key_file); return page_setup; } static void eom_print_save_key_file (GKeyFile *key_file) { gchar *filename; gchar *data; GError *error = NULL; const gchar *dot_dir = eom_util_dot_dir (); filename = g_build_filename (dot_dir, EOM_PRINT_SETTINGS_FILE, NULL); data = g_key_file_to_data (key_file, NULL, NULL); g_file_set_contents (filename, data, -1, &error); if (error) { g_warning ("Error saving print settings file: %s", error->message); g_error_free (error); } g_free (filename); g_free (data); } void eom_print_set_page_setup (GtkPageSetup *page_setup) { GKeyFile *key_file; key_file = eom_print_get_key_file (); if (key_file == NULL) { key_file = g_key_file_new (); } gtk_page_setup_to_key_file (page_setup, key_file, EOM_PAGE_SETUP_GROUP); eom_print_save_key_file (key_file); g_key_file_free (key_file); } GtkPrintSettings * eom_print_get_print_settings (void) { GtkPrintSettings *print_settings; GError *error = NULL; GKeyFile *key_file; key_file = eom_print_get_key_file (); if (key_file && g_key_file_has_group (key_file, EOM_PRINT_SETTINGS_GROUP)) { print_settings = gtk_print_settings_new_from_key_file (key_file, EOM_PRINT_SETTINGS_GROUP, &error); } else { print_settings = gtk_print_settings_new (); } if (error) { print_settings = gtk_print_settings_new (); g_warning ("Error loading print settings file: %s", error->message); g_error_free (error); } if (key_file) g_key_file_free (key_file); return print_settings; } void eom_print_set_print_settings (GtkPrintSettings *print_settings) { GKeyFile *key_file; key_file = eom_print_get_key_file (); if (key_file == NULL) { key_file = g_key_file_new (); } gtk_print_settings_to_key_file (print_settings, key_file, EOM_PRINT_SETTINGS_GROUP); eom_print_save_key_file (key_file); g_key_file_free (key_file); }