gtkprintbackendfile.c

来自「This GTK+ version 2.12.3. GTK+ is a mult」· C语言 代码 · 共 700 行 · 第 1/2 页

C
700
字号
/* GTK - The GIMP Toolkit * gtkprintbackendfile.c: Default implementation of GtkPrintBackend  * for printing to a file * Copyright (C) 2003, Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <cairo.h>#include <cairo-pdf.h>#include <cairo-ps.h>#include <glib/gi18n-lib.h>#include "gtkprintoperation.h"#include "gtkprintbackend.h"#include "gtkprintbackendfile.h"#include "gtkprinter.h"#include "gtkprinter-private.h"typedef struct _GtkPrintBackendFileClass GtkPrintBackendFileClass;#define GTK_PRINT_BACKEND_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_FILE, GtkPrintBackendFileClass))#define GTK_IS_PRINT_BACKEND_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_FILE))#define GTK_PRINT_BACKEND_FILE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_FILE, GtkPrintBackendFileClass))#define _STREAM_MAX_CHUNK_SIZE 8192static GType print_backend_file_type = 0;struct _GtkPrintBackendFileClass{  GtkPrintBackendClass parent_class;};struct _GtkPrintBackendFile{  GtkPrintBackend parent_instance;};typedef enum{  FORMAT_PDF,  FORMAT_PS,  N_FORMATS} OutputFormat;static const gchar* formats[N_FORMATS] ={  "pdf",  "ps"};static GObjectClass *backend_parent_class;static void                 gtk_print_backend_file_class_init      (GtkPrintBackendFileClass *class);static void                 gtk_print_backend_file_init            (GtkPrintBackendFile      *impl);static void                 file_printer_get_settings_from_options (GtkPrinter              *printer,								    GtkPrinterOptionSet     *options,								    GtkPrintSettings        *settings);static GtkPrinterOptionSet *file_printer_get_options               (GtkPrinter              *printer,								    GtkPrintSettings        *settings,								    GtkPageSetup            *page_setup,								    GtkPrintCapabilities     capabilities);static void                 file_printer_prepare_for_print         (GtkPrinter              *printer,								    GtkPrintJob             *print_job,								    GtkPrintSettings        *settings,								    GtkPageSetup            *page_setup);static void                 gtk_print_backend_file_print_stream    (GtkPrintBackend         *print_backend,								    GtkPrintJob             *job,								    GIOChannel              *data_io,								    GtkPrintJobCompleteFunc  callback,								    gpointer                 user_data,								    GDestroyNotify           dnotify);static cairo_surface_t *    file_printer_create_cairo_surface      (GtkPrinter              *printer,								    GtkPrintSettings        *settings,								    gdouble                  width,								    gdouble                  height,								    GIOChannel              *cache_io);static GList *              file_printer_list_papers               (GtkPrinter              *printer);static voidgtk_print_backend_file_register_type (GTypeModule *module){  static const GTypeInfo print_backend_file_info =  {    sizeof (GtkPrintBackendFileClass),    NULL,		/* base_init */    NULL,		/* base_finalize */    (GClassInitFunc) gtk_print_backend_file_class_init,    NULL,		/* class_finalize */    NULL,		/* class_data */    sizeof (GtkPrintBackendFile),    0,		/* n_preallocs */    (GInstanceInitFunc) gtk_print_backend_file_init,  };  print_backend_file_type = g_type_module_register_type (module,                                                         GTK_TYPE_PRINT_BACKEND,                                                         "GtkPrintBackendFile",                                                         &print_backend_file_info, 0);}G_MODULE_EXPORT void pb_module_init (GTypeModule *module){  gtk_print_backend_file_register_type (module);}G_MODULE_EXPORT void pb_module_exit (void){}  G_MODULE_EXPORT GtkPrintBackend * pb_module_create (void){  return gtk_print_backend_file_new ();}/* * GtkPrintBackendFile */GTypegtk_print_backend_file_get_type (void){  return print_backend_file_type;}/** * gtk_print_backend_file_new: * * Creates a new #GtkPrintBackendFile object. #GtkPrintBackendFile * implements the #GtkPrintBackend interface with direct access to * the filesystem using Unix/Linux API calls * * Return value: the new #GtkPrintBackendFile object **/GtkPrintBackend *gtk_print_backend_file_new (void){  return g_object_new (GTK_TYPE_PRINT_BACKEND_FILE, NULL);}static voidgtk_print_backend_file_class_init (GtkPrintBackendFileClass *class){  GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);  backend_parent_class = g_type_class_peek_parent (class);  backend_class->print_stream = gtk_print_backend_file_print_stream;  backend_class->printer_create_cairo_surface = file_printer_create_cairo_surface;  backend_class->printer_get_options = file_printer_get_options;  backend_class->printer_get_settings_from_options = file_printer_get_settings_from_options;  backend_class->printer_prepare_for_print = file_printer_prepare_for_print;  backend_class->printer_list_papers = file_printer_list_papers;}/* return N_FORMATS if no explicit format in the settings */static OutputFormatformat_from_settings (GtkPrintSettings *settings){  const gchar *value;  gint i;  if (settings == NULL)    return N_FORMATS;  value = gtk_print_settings_get (settings,                                  GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);  if (value == NULL)    return N_FORMATS;  for (i = 0; i < N_FORMATS; ++i)    if (strcmp (value, formats[i]) == 0)      break;  g_assert (i < N_FORMATS);  return (OutputFormat) i;}static gchar *output_file_from_settings (GtkPrintSettings *settings,			   const gchar      *default_format){  gchar *uri = NULL;    if (settings)    uri = g_strdup (gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_URI));  if (uri == NULL)    {       const gchar *extension;      gchar *name, *locale_name, *path;      if (default_format)        extension = default_format;      else        {          OutputFormat format;          format = format_from_settings (settings);          extension = format == FORMAT_PS ? "ps" : "pdf";        }       /* default filename used for print-to-file */       name = g_strdup_printf (_("output.%s"), extension);      locale_name = g_filename_from_utf8 (name, -1, NULL, NULL, NULL);      g_free (name);      if (locale_name != NULL)        {          path = g_build_filename (g_get_current_dir (), locale_name, NULL);          g_free (locale_name);          uri = g_filename_to_uri (path, NULL, NULL);          g_free (path);	}    }  return uri;}static cairo_status_t_cairo_write (void                *closure,              const unsigned char *data,              unsigned int         length){  GIOChannel *io = (GIOChannel *)closure;  gsize written;  GError *error;  error = NULL;  GTK_NOTE (PRINTING,            g_print ("FILE Backend: Writting %i byte chunk to temp file\n", length));  while (length > 0)     {      g_io_channel_write_chars (io, (const gchar *) data, length, &written, &error);      if (error != NULL)	{	  GTK_NOTE (PRINTING,                     g_print ("FILE Backend: Error writting to temp file, %s\n", error->message));          g_error_free (error);	  return CAIRO_STATUS_WRITE_ERROR;	}          GTK_NOTE (PRINTING,                g_print ("FILE Backend: Wrote %i bytes to temp file\n", written));            data += written;      length -= written;    }  return CAIRO_STATUS_SUCCESS;}static cairo_surface_t *file_printer_create_cairo_surface (GtkPrinter       *printer,				   GtkPrintSettings *settings,				   gdouble           width, 				   gdouble           height,				   GIOChannel       *cache_io){  cairo_surface_t *surface;  OutputFormat format;  format = format_from_settings (settings);  if (format == FORMAT_PS)    surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height);  else    surface = cairo_pdf_surface_create_for_stream (_cairo_write, cache_io, width, height);  /* TODO: DPI from settings object? */  cairo_surface_set_fallback_resolution (surface, 300, 300);  return surface;}typedef struct {  GtkPrintBackend *backend;  GtkPrintJobCompleteFunc callback;  GtkPrintJob *job;  GIOChannel *target_io;  gpointer user_data;  GDestroyNotify dnotify;} _PrintStreamData;static voidfile_print_cb (GtkPrintBackendFile *print_backend,               GError              *error,               gpointer            user_data){  _PrintStreamData *ps = (_PrintStreamData *) user_data;  GDK_THREADS_ENTER ();  if (ps->target_io != NULL)    g_io_channel_unref (ps->target_io);  if (ps->callback)    ps->callback (ps->job, ps->user_data, error);  if (ps->dnotify)    ps->dnotify (ps->user_data);  gtk_print_job_set_status (ps->job,			    (error != NULL)?GTK_PRINT_STATUS_FINISHED_ABORTED:GTK_PRINT_STATUS_FINISHED);  if (ps->job)    g_object_unref (ps->job);   g_free (ps);  GDK_THREADS_LEAVE ();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?