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.