21#include <poppler/glib/poppler.h>
34 PrintData( PopplerDocument* d ) :
41void draw_page( GtkPrintOperation* operation, GtkPrintContext* context, gint page_nr, gpointer user_data )
43 PrintData* print_data =
static_cast<PrintData*
>( user_data );
45 if( !print_data || !print_data->doc )
48 PopplerPage* page = poppler_document_get_page( print_data->doc, page_nr );
52 auto cleanup_page = std::unique_ptr<PopplerPage, decltype( &g_object_unref )>( page, &g_object_unref );
54 cairo_t* cr = gtk_print_context_get_cairo_context( context );
59 double page_width, page_height;
60 poppler_page_get_size( page, &page_width, &page_height );
63 double print_width = gtk_print_context_get_width( context );
64 double print_height = gtk_print_context_get_height( context );
67 auto cleanup_cairo = std::unique_ptr<cairo_t, decltype( &cairo_restore )>( cr, &cairo_restore );
69 if( print_data->fit_to_page )
72 double scale_x = print_width / page_width;
73 double scale_y = print_height / page_height;
74 double scale = std::min( scale_x, scale_y );
77 double scaled_width = page_width *
scale;
78 double scaled_height = page_height *
scale;
79 double offset_x = ( print_width - scaled_width ) / 2.0;
80 double offset_y = ( print_height - scaled_height ) / 2.0;
83 cairo_translate( cr, offset_x, offset_y );
88 cairo_set_source_rgb( cr, 1.0, 1.0, 1.0 );
92 poppler_page_render( page, cr );
95void begin_print_callback( GtkPrintOperation* operation, GtkPrintContext* context, gpointer user_data )
97 PrintData* print_data =
static_cast<PrintData*
>( user_data );
98 if( !print_data || !print_data->doc )
100 gtk_print_operation_cancel( operation );
104 int num_pages = poppler_document_get_n_pages( print_data->doc );
107 gtk_print_operation_cancel( operation );
111 gtk_print_operation_set_n_pages( operation, num_pages );
114void request_page_setup_callback( GtkPrintOperation* operation, GtkPrintContext* context, gint page_nr,
115 GtkPageSetup* setup, gpointer user_data )
117 PrintData* print_data =
static_cast<PrintData*
>( user_data );
119 if( !print_data || !print_data->doc )
122 PopplerPage* page = poppler_document_get_page( print_data->doc, page_nr );
128 double page_width, page_height;
129 poppler_page_get_size( page, &page_width, &page_height );
132 GtkPageOrientation orientation =
133 ( page_width > page_height ) ? GTK_PAGE_ORIENTATION_LANDSCAPE : GTK_PAGE_ORIENTATION_PORTRAIT;
134 gtk_page_setup_set_orientation( setup, orientation );
136 g_object_unref( page );
147 if( access( aFile.c_str(), R_OK ) != 0 )
151 gchar* uri = g_filename_to_uri( aFile.c_str(), NULL, NULL );
156 GError* error = NULL;
157 PopplerDocument* doc = poppler_document_new_from_file( uri, NULL, &error );
162 g_error_free( error );
169 auto cleanup_doc = std::unique_ptr<PopplerDocument, decltype(&g_object_unref)>(doc, &g_object_unref);
172 int num_pages = poppler_document_get_n_pages( doc );
178 PrintData print_data( doc );
179 print_data.fit_to_page = fit_to_page;
182 GtkPrintOperation* op = gtk_print_operation_new();
187 auto cleanup_op = std::unique_ptr<GtkPrintOperation, decltype( &g_object_unref )>( op, &g_object_unref );
190 gtk_print_operation_set_use_full_page( op, FALSE );
191 gtk_print_operation_set_unit( op, GTK_UNIT_POINTS );
194 g_signal_connect( op,
"begin-print", G_CALLBACK( begin_print_callback ), &print_data );
195 g_signal_connect( op,
"draw-page", G_CALLBACK( draw_page ), &print_data );
196 g_signal_connect( op,
"request-page-setup", G_CALLBACK( request_page_setup_callback ), &print_data );
200 GtkPrintOperationResult
result =
201 gtk_print_operation_run( op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, &error );
208 g_error_free( error );
215 case GTK_PRINT_OPERATION_RESULT_APPLY: return_result =
PRINT_RESULT::OK;
break;
217 case GTK_PRINT_OPERATION_RESULT_ERROR:
222 return return_result;
wxString result
Test unit parsing edge cases and error handling.