1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        wx/gtk/print.cpp 
   3 // Author:      Anthony Bretaudeau 
   4 // Purpose:     GTK printing support 
   7 // Copyright:   (c) 2007 wxWidgets development team 
   8 // Licence:     wxWindows Licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // For compilers that support precompilation, includes "wx/wx.h". 
  12 #include "wx/wxprec.h" 
  20 #include "wx/gtk/print.h" 
  24 #include "wx/dcmemory.h" 
  25 #include "wx/dcprint.h" 
  29 #include "wx/module.h" 
  33 #include "wx/fontutil.h" 
  34 #include "wx/gtk/private.h" 
  35 #include "wx/dynlib.h" 
  39 #include <gtk/gtkpagesetupunixdialog.h> 
  41 #if wxUSE_GRAPHICS_CONTEXT 
  42 #include "wx/graphics.h" 
  46 wxFORCE_LINK_THIS_MODULE(gtk_print
) 
  48 #if wxUSE_LIBGNOMEPRINT 
  49 #include "wx/gtk/gnome/gprint.h" 
  52 #include "wx/gtk/private/object.h" 
  54 // Usefull to convert angles from/to Rad to/from Deg. 
  55 static const double RAD2DEG  
= 180.0 / M_PI
; 
  56 static const double DEG2RAD  
= M_PI 
/ 180.0; 
  58 //---------------------------------------------------------------------------- 
  60 // Initialized when starting the app : if it successfully load the gtk-print framework, 
  61 // it uses it. If not, it falls back to gnome print (see /gtk/gnome/gprint.cpp) then 
  62 // to postscript if gnomeprint is not available. 
  63 //---------------------------------------------------------------------------- 
  65 class wxGtkPrintModule
: public wxModule
 
  70 #if wxUSE_LIBGNOMEPRINT 
  71         // This module must be initialized AFTER gnomeprint's one 
  72         AddDependency(CLASSINFO(wxGnomePrintModule
)); 
  79     DECLARE_DYNAMIC_CLASS(wxGtkPrintModule
) 
  82 bool wxGtkPrintModule::OnInit() 
  84     if (gtk_check_version(2,10,0) == NULL
) 
  85         wxPrintFactory::SetPrintFactory( new wxGtkPrintFactory 
); 
  89 IMPLEMENT_DYNAMIC_CLASS(wxGtkPrintModule
, wxModule
) 
  91 //---------------------------------------------------------------------------- 
  93 //---------------------------------------------------------------------------- 
  95 wxPrinterBase
* wxGtkPrintFactory::CreatePrinter( wxPrintDialogData 
*data 
) 
  97     return new wxGtkPrinter( data 
); 
 100 wxPrintPreviewBase 
*wxGtkPrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 101                                                     wxPrintout 
*printout
, 
 102                                                     wxPrintDialogData 
*data 
) 
 104     return new wxGtkPrintPreview( preview
, printout
, data 
); 
 107 wxPrintPreviewBase 
*wxGtkPrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 108                                                     wxPrintout 
*printout
, 
 111     return new wxGtkPrintPreview( preview
, printout
, data 
); 
 114 wxPrintDialogBase 
*wxGtkPrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 115                                                   wxPrintDialogData 
*data 
) 
 117     return new wxGtkPrintDialog( parent
, data 
); 
 120 wxPrintDialogBase 
*wxGtkPrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 123     return new wxGtkPrintDialog( parent
, data 
); 
 126 wxPageSetupDialogBase 
*wxGtkPrintFactory::CreatePageSetupDialog( wxWindow 
*parent
, 
 127                                                           wxPageSetupDialogData 
* data 
) 
 129     return new wxGtkPageSetupDialog( parent
, data 
); 
 132 bool wxGtkPrintFactory::HasPrintSetupDialog() 
 138 wxGtkPrintFactory::CreatePrintSetupDialog(wxWindow 
* WXUNUSED(parent
), 
 139                                           wxPrintData 
* WXUNUSED(data
)) 
 144 wxDCImpl
* wxGtkPrintFactory::CreatePrinterDCImpl( wxPrinterDC 
*owner
, const wxPrintData
& data 
) 
 146     return new wxGtkPrinterDCImpl( owner
, data 
); 
 149 bool wxGtkPrintFactory::HasOwnPrintToFile() 
 154 bool wxGtkPrintFactory::HasPrinterLine() 
 159 wxString 
wxGtkPrintFactory::CreatePrinterLine() 
 162     return wxEmptyString
; 
 165 bool wxGtkPrintFactory::HasStatusLine() 
 171 wxString 
wxGtkPrintFactory::CreateStatusLine() 
 174     return wxEmptyString
; 
 177 wxPrintNativeDataBase 
*wxGtkPrintFactory::CreatePrintNativeData() 
 179     return new wxGtkPrintNativeData
; 
 182 //---------------------------------------------------------------------------- 
 183 // Callback functions for Gtk Printings. 
 184 //---------------------------------------------------------------------------- 
 186 // We use it to pass useful objects to GTK printing callback functions. 
 187 struct wxPrinterToGtkData
 
 189    wxGtkPrinter 
* printer
; 
 190    wxPrintout 
* printout
; 
 195     static void gtk_begin_print_callback (GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, gpointer user_data
) 
 197         wxPrinterToGtkData 
*data 
= (wxPrinterToGtkData 
*) user_data
; 
 199         data
->printer
->BeginPrint(data
->printout
, operation
, context
); 
 202     static void gtk_draw_page_print_callback (GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, gint page_nr
, gpointer user_data
) 
 204         wxPrinterToGtkData 
*data 
= (wxPrinterToGtkData 
*) user_data
; 
 206         data
->printer
->DrawPage(data
->printout
, operation
, context
, page_nr
); 
 209     static void gtk_end_print_callback(GtkPrintOperation 
* WXUNUSED(operation
), 
 210                                        GtkPrintContext 
* WXUNUSED(context
), 
 213         wxPrintout 
*printout 
= (wxPrintout 
*) user_data
; 
 215         printout
->OnEndPrinting(); 
 219 //---------------------------------------------------------------------------- 
 220 // wxGtkPrintNativeData 
 221 //---------------------------------------------------------------------------- 
 223 IMPLEMENT_CLASS(wxGtkPrintNativeData
, wxPrintNativeDataBase
) 
 225 wxGtkPrintNativeData::wxGtkPrintNativeData() 
 227     m_config 
= gtk_print_settings_new(); 
 228     m_job 
= gtk_print_operation_new(); 
 232 wxGtkPrintNativeData::~wxGtkPrintNativeData() 
 234     g_object_unref(m_job
); 
 235     g_object_unref(m_config
); 
 238 // Convert datas stored in m_config to a wxPrintData. 
 239 // Called by wxPrintData::ConvertFromNative(). 
 240 bool wxGtkPrintNativeData::TransferTo( wxPrintData 
&data 
) 
 245     int resolution 
= gtk_print_settings_get_resolution(m_config
); 
 246     if ( resolution 
> 0 ) 
 248         // if resolution is explicitly set, use it 
 249         data
.SetQuality(resolution
); 
 251     else // use more vague "quality" 
 253         GtkPrintQuality quality 
= gtk_print_settings_get_quality(m_config
); 
 254         if (quality 
== GTK_PRINT_QUALITY_HIGH
) 
 255             data
.SetQuality(wxPRINT_QUALITY_HIGH
); 
 256         else if (quality 
== GTK_PRINT_QUALITY_LOW
) 
 257             data
.SetQuality(wxPRINT_QUALITY_LOW
); 
 258         else if (quality 
== GTK_PRINT_QUALITY_DRAFT
) 
 259             data
.SetQuality(wxPRINT_QUALITY_DRAFT
); 
 261             data
.SetQuality(wxPRINT_QUALITY_MEDIUM
); 
 264     data
.SetNoCopies(gtk_print_settings_get_n_copies(m_config
)); 
 266     data
.SetColour(gtk_print_settings_get_use_color(m_config
)); 
 268     switch (gtk_print_settings_get_duplex(m_config
)) 
 270         case GTK_PRINT_DUPLEX_SIMPLEX
:      data
.SetDuplex (wxDUPLEX_SIMPLEX
); 
 273         case GTK_PRINT_DUPLEX_HORIZONTAL
:   data
.SetDuplex (wxDUPLEX_HORIZONTAL
); 
 277         case GTK_PRINT_DUPLEX_VERTICAL
:      data
.SetDuplex (wxDUPLEX_VERTICAL
); 
 281     GtkPageOrientation orientation 
= gtk_print_settings_get_orientation (m_config
); 
 282     if (orientation 
== GTK_PAGE_ORIENTATION_PORTRAIT
) 
 284         data
.SetOrientation(wxPORTRAIT
); 
 285         data
.SetOrientationReversed(false); 
 287     else if (orientation 
== GTK_PAGE_ORIENTATION_LANDSCAPE
) 
 289         data
.SetOrientation(wxLANDSCAPE
); 
 290         data
.SetOrientationReversed(false); 
 292     else if (orientation 
== GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
) 
 294         data
.SetOrientation(wxPORTRAIT
); 
 295         data
.SetOrientationReversed(true); 
 297     else if (orientation 
== GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
) 
 299         data
.SetOrientation(wxLANDSCAPE
); 
 300         data
.SetOrientationReversed(true); 
 303     data
.SetCollate(gtk_print_settings_get_collate (m_config
)); 
 305     // Paper formats : these are the most common paper formats. 
 306     GtkPaperSize 
*paper_size 
= gtk_print_settings_get_paper_size (m_config
); 
 308         data
.SetPaperId(wxPAPER_NONE
); 
 309     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_A3
))) 
 310         data
.SetPaperId(wxPAPER_A3
); 
 311     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_A4
))) 
 312         data
.SetPaperId(wxPAPER_A4
); 
 313     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_A5
))) 
 314         data
.SetPaperId(wxPAPER_A5
); 
 315     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_B5
))) 
 316         data
.SetPaperId(wxPAPER_B5
); 
 317     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_LETTER
))) 
 318         data
.SetPaperId(wxPAPER_LETTER
); 
 319     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_LEGAL
))) 
 320         data
.SetPaperId(wxPAPER_LEGAL
); 
 321     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE
))) 
 322         data
.SetPaperId(wxPAPER_EXECUTIVE
); 
 323     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"na_number-10"))) 
 324         data
.SetPaperId(wxPAPER_ENV_10
); 
 325     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c5"))) 
 326         data
.SetPaperId(wxPAPER_ENV_C5
); 
 327     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c6"))) 
 328         data
.SetPaperId(wxPAPER_ENV_C6
); 
 329     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"jis-b5"))) 
 330         data
.SetPaperId(wxPAPER_B5_TRANSVERSE
); 
 331     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b5"))) 
 332         data
.SetPaperId(wxPAPER_ENV_B5
); 
 333     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"na_monarch"))) 
 334         data
.SetPaperId(wxPAPER_ENV_MONARCH
); 
 335     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-c"))) 
 336         data
.SetPaperId( wxPAPER_CSHEET
); 
 337     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-d"))) 
 338         data
.SetPaperId( wxPAPER_DSHEET
); 
 339     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-e"))) 
 340         data
.SetPaperId( wxPAPER_ESHEET
); 
 341     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"letter"))) 
 342         data
.SetPaperId( wxPAPER_LETTERSMALL
); 
 343     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-b"))) 
 344         data
.SetPaperId( wxPAPER_TABLOID
); 
 345     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"ledger"))) 
 346         data
.SetPaperId( wxPAPER_LEDGER
); 
 347     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"statement"))) 
 348         data
.SetPaperId( wxPAPER_STATEMENT
); 
 349     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( GTK_PAPER_NAME_A4 
))) 
 350         data
.SetPaperId( wxPAPER_A4SMALL
); 
 351     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b4"))) 
 352         data
.SetPaperId( wxPAPER_B4
); 
 353     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"folio"))) 
 354         data
.SetPaperId( wxPAPER_FOLIO
); 
 355     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"quarto"))) 
 356         data
.SetPaperId( wxPAPER_QUARTO
); 
 357     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"10x14"))) 
 358         data
.SetPaperId( wxPAPER_10X14
); 
 359     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"ledger"))) 
 360         data
.SetPaperId( wxPAPER_11X17
); 
 361     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"letter"))) 
 362         data
.SetPaperId( wxPAPER_NOTE
); 
 363     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"na-number-9-envelope"))) 
 364         data
.SetPaperId( wxPAPER_ENV_9
); 
 365     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"number-11"))) 
 366         data
.SetPaperId( wxPAPER_ENV_11
); 
 367     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"number-12"))) 
 368         data
.SetPaperId( wxPAPER_ENV_12
); 
 369     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"number-14"))) 
 370         data
.SetPaperId( wxPAPER_ENV_14
); 
 371     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-designated"))) 
 372         data
.SetPaperId( wxPAPER_ENV_DL
); 
 373     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c3"))) 
 374         data
.SetPaperId( wxPAPER_ENV_C3
); 
 375     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c4"))) 
 376         data
.SetPaperId( wxPAPER_ENV_C4
); 
 377     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"c6/c5"))) 
 378         data
.SetPaperId( wxPAPER_ENV_C65
); 
 379     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b4"))) 
 380         data
.SetPaperId( wxPAPER_ENV_B4
); 
 381     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b6"))) 
 382             data
.SetPaperId( wxPAPER_ENV_B6
); 
 383     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"Italian"))) 
 384         data
.SetPaperId( wxPAPER_ENV_ITALY
); 
 385     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"personal"))) 
 386         data
.SetPaperId( wxPAPER_ENV_PERSONAL
); 
 387     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"fanfold-us"))) 
 388         data
.SetPaperId( wxPAPER_FANFOLD_US
); 
 389     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"fanfold-European"))) 
 390         data
.SetPaperId( wxPAPER_FANFOLD_STD_GERMAN
); 
 391     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"foolscap"))) 
 392         data
.SetPaperId( wxPAPER_FANFOLD_LGL_GERMAN
); 
 394         data
.SetPaperId(wxPAPER_NONE
); 
 396     data
.SetPrinterName(gtk_print_settings_get_printer(m_config
)); 
 401 // Put datas given by the wxPrintData into m_config. 
 402 // Called by wxPrintData::ConvertToNative(). 
 403 bool wxGtkPrintNativeData::TransferFrom( const wxPrintData 
&data 
) 
 408     wxPrintQuality quality 
= data
.GetQuality(); 
 409     if (quality 
== wxPRINT_QUALITY_HIGH
) 
 410         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_HIGH
); 
 411     else if (quality 
== wxPRINT_QUALITY_MEDIUM
) 
 412         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_NORMAL
); 
 413     else if (quality 
== wxPRINT_QUALITY_LOW
) 
 414         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_LOW
); 
 415     else if (quality 
== wxPRINT_QUALITY_DRAFT
) 
 416         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_DRAFT
); 
 417     else if (quality 
> 1) 
 418         gtk_print_settings_set_resolution (m_config
, quality
); 
 420         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_NORMAL
); 
 422     gtk_print_settings_set_n_copies(m_config
, data
.GetNoCopies()); 
 424     gtk_print_settings_set_use_color(m_config
, data
.GetColour()); 
 426     switch (data
.GetDuplex()) 
 428         case wxDUPLEX_SIMPLEX
:      gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_SIMPLEX
); 
 431         case wxDUPLEX_HORIZONTAL
:   gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_HORIZONTAL
); 
 435         case wxDUPLEX_VERTICAL
:      gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_VERTICAL
); 
 439     if (!data
.IsOrientationReversed()) 
 441         if (data
.GetOrientation() == wxLANDSCAPE
) 
 442             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_LANDSCAPE
); 
 444             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_PORTRAIT
); 
 447         if (data
.GetOrientation() == wxLANDSCAPE
) 
 448             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
); 
 450             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
); 
 453     gtk_print_settings_set_collate (m_config
, data
.GetCollate()); 
 455     // Paper formats: these are the most common paper formats. 
 456     switch (data
.GetPaperId()) 
 458         case wxPAPER_A3
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A3
)); 
 460         case wxPAPER_A4
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A4
)); 
 462         case wxPAPER_A5
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A5
)); 
 464         case wxPAPER_B5_TRANSVERSE
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "jis-b5")); 
 466         case wxPAPER_B5
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_B5
)); 
 468         case wxPAPER_LETTER
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_LETTER
)); 
 470         case wxPAPER_LEGAL
:     gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_LEGAL
)); 
 472         case wxPAPER_EXECUTIVE
: gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE
)); 
 474         case wxPAPER_ENV_10
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na_number-10")); 
 476         case wxPAPER_ENV_C5
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c5")); 
 478         case wxPAPER_ENV_C6
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c6")); 
 480         case wxPAPER_ENV_B5
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c5b5")); 
 482         case wxPAPER_ENV_MONARCH
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na_monarch")); 
 484         case wxPAPER_CSHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-c")); 
 486         case wxPAPER_DSHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-d")); 
 488         case wxPAPER_ESHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-e")); 
 490         case wxPAPER_LETTERSMALL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "letter")); 
 492         case wxPAPER_TABLOID
:   gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-b")); 
 494         case wxPAPER_LEDGER
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "ledger")); 
 496         case wxPAPER_STATEMENT
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "statement")); 
 498         case wxPAPER_A4SMALL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A4
)); 
 500         case wxPAPER_B4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b4")); 
 502         case wxPAPER_FOLIO
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "folio")); 
 504         case wxPAPER_QUARTO
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "quarto")); 
 506         case wxPAPER_10X14
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "10x14")); 
 508         case wxPAPER_11X17
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "ledger")); 
 510         case wxPAPER_NOTE
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "letter")); 
 512         case wxPAPER_ENV_9
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na-number-9-envelope")); 
 514         case wxPAPER_ENV_11
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-11")); 
 516         case wxPAPER_ENV_12
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-12")); 
 518         case wxPAPER_ENV_14
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-14")); 
 520         case wxPAPER_ENV_DL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-designated")); 
 522         case wxPAPER_ENV_C3
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c3")); 
 524         case wxPAPER_ENV_C4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c4")); 
 526         case wxPAPER_ENV_C65
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "c6/c5")); 
 528         case wxPAPER_ENV_B4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b4")); 
 530         case wxPAPER_ENV_B6
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b6")); 
 532         case wxPAPER_ENV_ITALY
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "Italian")); 
 534         case wxPAPER_ENV_PERSONAL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "personal")); 
 536         case wxPAPER_FANFOLD_US
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "fanfold-us")); 
 538         case wxPAPER_FANFOLD_STD_GERMAN
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "fanfold-European")); 
 540         case wxPAPER_FANFOLD_LGL_GERMAN
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "foolscap")); 
 546     gtk_print_settings_set_printer(m_config
, data
.GetPrinterName().utf8_str()); 
 551 void wxGtkPrintNativeData::SetPrintConfig( GtkPrintSettings 
* config 
) 
 554         m_config 
= gtk_print_settings_copy(config
); 
 557 // Extract page setup from settings. 
 558 GtkPageSetup
* wxGtkPrintNativeData::GetPageSetupFromSettings(GtkPrintSettings
* settings
) 
 560     GtkPageSetup
* page_setup 
= gtk_page_setup_new(); 
 561     gtk_page_setup_set_orientation (page_setup
, gtk_print_settings_get_orientation (settings
)); 
 563     GtkPaperSize 
*paper_size 
= gtk_print_settings_get_paper_size (settings
); 
 564     if (paper_size 
!= NULL
) 
 565         gtk_page_setup_set_paper_size_and_default_margins (page_setup
, paper_size
); 
 570 // Insert page setup into a given GtkPrintSettings. 
 571 void wxGtkPrintNativeData::SetPageSetupToSettings(GtkPrintSettings
* settings
, GtkPageSetup
* page_setup
) 
 573     gtk_print_settings_set_orientation ( settings
, gtk_page_setup_get_orientation (page_setup
)); 
 574     gtk_print_settings_set_paper_size ( settings
, gtk_page_setup_get_paper_size (page_setup
)); 
 577 //---------------------------------------------------------------------------- 
 579 //---------------------------------------------------------------------------- 
 581 IMPLEMENT_CLASS(wxGtkPrintDialog
, wxPrintDialogBase
) 
 583 wxGtkPrintDialog::wxGtkPrintDialog( wxWindow 
*parent
, wxPrintDialogData 
*data 
) 
 584                     : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"), 
 585                                wxPoint(0, 0), wxSize(600, 600), 
 586                                wxDEFAULT_DIALOG_STYLE 
| 
 590         m_printDialogData 
= *data
; 
 596 wxGtkPrintDialog::wxGtkPrintDialog( wxWindow 
*parent
, wxPrintData 
*data 
) 
 597                     : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"), 
 598                                wxPoint(0, 0), wxSize(600, 600), 
 599                                wxDEFAULT_DIALOG_STYLE 
| 
 603         m_printDialogData 
= *data
; 
 610 wxGtkPrintDialog::~wxGtkPrintDialog() 
 614 // This is called even if we actually don't want the dialog to appear. 
 615 int wxGtkPrintDialog::ShowModal() 
 617     GtkPrintOperationResult response
; 
 619     // We need to restore the settings given in the constructor. 
 620     wxPrintData data 
= m_printDialogData
.GetPrintData(); 
 621     wxGtkPrintNativeData 
*native 
= 
 622       (wxGtkPrintNativeData
*) data
.GetNativeData(); 
 623     data
.ConvertToNative(); 
 625     GtkPrintSettings 
* settings 
= native
->GetPrintConfig(); 
 627     // We have to restore pages to print here because they're stored in a wxPrintDialogData and ConvertToNative only works for wxPrintData. 
 628     int fromPage 
= m_printDialogData
.GetFromPage(); 
 629     int toPage 
= m_printDialogData
.GetToPage(); 
 630     if (m_printDialogData
.GetSelection()) 
 631         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_CURRENT
); 
 632     else if (m_printDialogData
.GetAllPages()) 
 633         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_ALL
); 
 635         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_RANGES
); 
 637         range 
= g_new (GtkPageRange
, 1); 
 638         range
[0].start 
= fromPage
-1; 
 639         range
[0].end 
= (toPage 
>= fromPage
) ? toPage
-1 : fromPage
-1; 
 640         gtk_print_settings_set_page_ranges (settings
, range
, 1); 
 643     GtkPrintOperation 
* const printOp 
= native
->GetPrintJob(); 
 645     // If the settings are OK, we restore it. 
 646     if (settings 
!= NULL
) 
 647         gtk_print_operation_set_print_settings (printOp
, settings
); 
 648     gtk_print_operation_set_default_page_setup (printOp
, native
->GetPageSetupFromSettings(settings
)); 
 650     // Show the dialog if needed. 
 651     GError
* gError 
= NULL
; 
 653         response 
= gtk_print_operation_run (printOp
, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
, GTK_WINDOW(gtk_widget_get_toplevel(m_parent
->m_widget
) ), &gError
); 
 655         response 
= gtk_print_operation_run (printOp
, GTK_PRINT_OPERATION_ACTION_PRINT
, GTK_WINDOW(gtk_widget_get_toplevel(m_parent
->m_widget
)), &gError
); 
 657     // Does everything went well? 
 658     if (response 
== GTK_PRINT_OPERATION_RESULT_CANCEL
) 
 662     else if (response 
== GTK_PRINT_OPERATION_RESULT_ERROR
) 
 664         g_error_free (gError
); 
 665         wxLogError(_("Error while printing: ") + wxString::Format(_("%s"), gError
->message
)); 
 666         return wxID_NO
; // We use wxID_NO because there is no wxID_ERROR available 
 669     // Now get the settings and save it. 
 670     GtkPrintSettings
* newSettings 
= gtk_print_operation_get_print_settings(printOp
); 
 671     native
->SetPrintConfig(newSettings
); 
 672     data
.ConvertFromNative(); 
 674     // Set PrintDialogData variables 
 675     m_printDialogData
.SetPrintData(data
); 
 676     m_printDialogData
.SetCollate(data
.GetCollate()); 
 677     m_printDialogData
.SetNoCopies(data
.GetNoCopies()); 
 678     m_printDialogData
.SetPrintToFile(data
.GetPrinterName() == "Print to File"); 
 680     // Same problem as a few lines before. 
 681     switch (gtk_print_settings_get_print_pages(newSettings
)) 
 683         case GTK_PRINT_PAGES_CURRENT
: 
 684             m_printDialogData
.SetSelection( true ); 
 686         case GTK_PRINT_PAGES_RANGES
: 
 687             {// wxWidgets doesn't support multiple ranges, so we can only save the first one even if the user wants to print others. 
 688             // For example, the user enters "1-3;5-7" in the dialog: pages 1-3 and 5-7 will be correctly printed when the user 
 689             // will hit "OK" button. However we can only save 1-3 in the print data. 
 692             range 
= gtk_print_settings_get_page_ranges (newSettings
, &num_ranges
); 
 695                 m_printDialogData
.SetFromPage( range
[0].start 
); 
 696                 m_printDialogData
.SetToPage( range
[0].end 
); 
 699                 m_printDialogData
.SetAllPages( true ); 
 700                 m_printDialogData
.SetFromPage( 0 ); 
 701                 m_printDialogData
.SetToPage( 9999 ); 
 704         case GTK_PRINT_PAGES_ALL
: 
 706             m_printDialogData
.SetAllPages( true ); 
 707             m_printDialogData
.SetFromPage( 0 ); 
 708             m_printDialogData
.SetToPage( 9999 ); 
 715 //---------------------------------------------------------------------------- 
 716 // wxGtkPageSetupDialog 
 717 //---------------------------------------------------------------------------- 
 719 IMPLEMENT_CLASS(wxGtkPageSetupDialog
, wxPageSetupDialogBase
) 
 721 wxGtkPageSetupDialog::wxGtkPageSetupDialog( wxWindow 
*parent
, 
 722                             wxPageSetupDialogData
* data 
) 
 725         m_pageDialogData 
= *data
; 
 730 wxGtkPageSetupDialog::~wxGtkPageSetupDialog() 
 734 int wxGtkPageSetupDialog::ShowModal() 
 737     m_pageDialogData
.GetPrintData().ConvertToNative(); 
 738     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) m_pageDialogData
.GetPrintData().GetNativeData(); 
 739     GtkPrintSettings
* nativeData 
= native
->GetPrintConfig(); 
 741     // We only need the pagesetup data which are part of the settings. 
 742     GtkPageSetup
* oldPageSetup 
= native
->GetPageSetupFromSettings(nativeData
); 
 744     // If the user used a custom paper format the last time he printed, we have to restore it too. 
 745     if (m_pageDialogData
.GetPrintData().GetPaperId() == wxPAPER_NONE
) 
 747         wxSize customPaperSize 
= m_pageDialogData
.GetPaperSize(); 
 748         if (customPaperSize
.GetWidth() > 0 && customPaperSize
.GetHeight() > 0) 
 750             wxString title 
= _("Custom size"); 
 751             GtkPaperSize
* customSize 
= gtk_paper_size_new_custom ("custom", title
.mb_str(), (gdouble
) customPaperSize
.GetWidth(), (gdouble
) customPaperSize
.GetHeight(), GTK_UNIT_MM
); 
 752             gtk_page_setup_set_paper_size_and_default_margins (oldPageSetup
, customSize
); 
 753             g_object_unref(customSize
); 
 758     // Set selected printer 
 759     gtk_print_settings_set(nativeData
, "format-for-printer", 
 760                            gtk_print_settings_get_printer(nativeData
)); 
 762     // Create custom dialog 
 763     wxString 
title(GetTitle()); 
 765         title 
= _("Page Setup"); 
 767         dlg 
= gtk_page_setup_unix_dialog_new(title
.utf8_str(), 
 768                                              GTK_WINDOW(m_parent
->m_widget
)); 
 770     gtk_page_setup_unix_dialog_set_print_settings( 
 771         GTK_PAGE_SETUP_UNIX_DIALOG(dlg
), nativeData
); 
 772     gtk_page_setup_unix_dialog_set_page_setup( 
 773         GTK_PAGE_SETUP_UNIX_DIALOG(dlg
), oldPageSetup
); 
 775     int result 
= gtk_dialog_run(GTK_DIALOG(dlg
)); 
 776     gtk_widget_hide(dlg
); 
 780         case GTK_RESPONSE_OK
: 
 781         case GTK_RESPONSE_APPLY
: 
 783                 // Store Selected Printer Name 
 784                 gtk_print_settings_set_printer
 
 787                     gtk_print_settings_get(nativeData
, "format-for-printer") 
 790                 wxGtkObject
<GtkPageSetup
> 
 791                     newPageSetup(gtk_page_setup_unix_dialog_get_page_setup( 
 792                                         GTK_PAGE_SETUP_UNIX_DIALOG(dlg
))); 
 793                 native
->SetPageSetupToSettings(nativeData
, newPageSetup
); 
 795                 m_pageDialogData
.GetPrintData().ConvertFromNative(); 
 797                 // Store custom paper format if any. 
 798                 if ( m_pageDialogData
.GetPrintData().GetPaperId() == wxPAPER_NONE 
) 
 800                     gdouble ml
,mr
,mt
,mb
,pw
,ph
; 
 801                     ml 
= gtk_page_setup_get_left_margin (newPageSetup
, GTK_UNIT_MM
); 
 802                     mr 
= gtk_page_setup_get_right_margin (newPageSetup
, GTK_UNIT_MM
); 
 803                     mt 
= gtk_page_setup_get_top_margin (newPageSetup
, GTK_UNIT_MM
); 
 804                     mb 
= gtk_page_setup_get_bottom_margin (newPageSetup
, GTK_UNIT_MM
); 
 806                     pw 
= gtk_page_setup_get_paper_width (newPageSetup
, GTK_UNIT_MM
); 
 807                     ph 
= gtk_page_setup_get_paper_height (newPageSetup
, GTK_UNIT_MM
); 
 809                     m_pageDialogData
.SetMarginTopLeft(wxPoint((int)(ml
+0.5), 
 811                     m_pageDialogData
.SetMarginBottomRight(wxPoint((int)(mr
+0.5), 
 814                     m_pageDialogData
.SetPaperSize(wxSize((int)(pw
+0.5), 
 823         case GTK_RESPONSE_CANCEL
: 
 824             result 
= wxID_CANCEL
; 
 828     gtk_widget_destroy(dlg
); 
 833 //---------------------------------------------------------------------------- 
 835 //---------------------------------------------------------------------------- 
 837 IMPLEMENT_CLASS(wxGtkPrinter
, wxPrinterBase
) 
 839 wxGtkPrinter::wxGtkPrinter( wxPrintDialogData 
*data 
) : 
 840     wxPrinterBase( data 
) 
 845         m_printDialogData 
= *data
; 
 848 wxGtkPrinter::~wxGtkPrinter() 
 852 bool wxGtkPrinter::Print(wxWindow 
*parent
, wxPrintout 
*printout
, bool prompt 
) 
 856         sm_lastError 
= wxPRINTER_ERROR
; 
 860     // Let's correct the PageInfo just in case the app gives wrong values. 
 861     int fromPage
, toPage
; 
 862     int minPage
, maxPage
; 
 863     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 864     m_printDialogData
.SetAllPages(true); 
 866     if (minPage 
< 1) minPage 
= 1; 
 867     if (maxPage 
< 1) maxPage 
= 9999; 
 868     if (maxPage 
< minPage
) maxPage 
= minPage
; 
 870     m_printDialogData
.SetMinPage(minPage
); 
 871     m_printDialogData
.SetMaxPage(maxPage
); 
 874         if (fromPage 
< minPage
) fromPage 
= minPage
; 
 875         else if (fromPage 
> maxPage
) fromPage 
= maxPage
; 
 876         m_printDialogData
.SetFromPage(fromPage
); 
 880         m_printDialogData
.SetToPage(toPage
); 
 881         if (toPage 
> maxPage
) toPage 
= maxPage
; 
 882         else if (toPage 
< minPage
) toPage 
= minPage
; 
 885     if (((minPage 
!= fromPage
) && fromPage 
!= 0) || ((maxPage 
!= toPage
) && toPage 
!= 0)) m_printDialogData
.SetAllPages(false); 
 888     wxPrintData printdata 
= GetPrintDialogData().GetPrintData(); 
 889     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) printdata
.GetNativeData(); 
 891     GtkPrintOperation 
* const printOp 
= native
->GetPrintJob(); 
 893     wxPrinterToGtkData dataToSend
; 
 894     dataToSend
.printer 
= this; 
 895     dataToSend
.printout 
= printout
; 
 897     // These Gtk signals are caught here. 
 898     g_signal_connect (printOp
, "begin-print", G_CALLBACK (gtk_begin_print_callback
), &dataToSend
); 
 899     g_signal_connect (printOp
, "draw-page", G_CALLBACK (gtk_draw_page_print_callback
), &dataToSend
); 
 900     g_signal_connect (printOp
, "end-print", G_CALLBACK (gtk_end_print_callback
), printout
); 
 902     // This is used to setup the DC and 
 903     // show the dialog if desired 
 904     wxGtkPrintDialog 
dialog( parent
, &m_printDialogData 
); 
 905     dialog
.SetPrintDC(m_dc
); 
 906     dialog
.SetShowDialog(prompt
); 
 908     // doesn't necessarily show 
 909     int ret 
= dialog
.ShowModal(); 
 910     if (ret 
== wxID_CANCEL
) 
 912         sm_lastError 
= wxPRINTER_CANCELLED
; 
 916         sm_lastError 
= wxPRINTER_ERROR
; 
 917         wxFAIL_MSG(_("The print dialog returned an error.")); 
 920     return (sm_lastError 
== wxPRINTER_NO_ERROR
); 
 923 void wxGtkPrinter::BeginPrint(wxPrintout 
*printout
, GtkPrintOperation 
*operation
, GtkPrintContext 
*context
) 
 925     wxPrintData printdata 
= GetPrintDialogData().GetPrintData(); 
 926     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) printdata
.GetNativeData(); 
 928     // We need to update printdata with the new data from the dialog and we 
 929     // have to do this here because this method needs this new data and we 
 930     // cannot update it earlier 
 931     native
->SetPrintConfig(gtk_print_operation_get_print_settings(operation
)); 
 932     printdata
.ConvertFromNative(); 
 934     SetPrintContext(context
); 
 935     native
->SetPrintContext( context 
); 
 937     wxPrinterDC 
*printDC 
= new wxPrinterDC( printdata 
); 
 942         if (sm_lastError 
!= wxPRINTER_CANCELLED
) 
 944             sm_lastError 
= wxPRINTER_ERROR
; 
 945             wxFAIL_MSG(_("The wxGtkPrinterDC cannot be used.")); 
 950     printout
->SetPPIScreen(wxGetDisplayPPI()); 
 951     printout
->SetPPIPrinter( printDC
->GetResolution(), 
 952                              printDC
->GetResolution() ); 
 954     printout
->SetDC(m_dc
); 
 957     m_dc
->GetSize(&w
, &h
); 
 958     printout
->SetPageSizePixels((int)w
, (int)h
); 
 959     printout
->SetPaperRectPixels(wxRect(0, 0, w
, h
)); 
 961     m_dc
->GetSizeMM(&mw
, &mh
); 
 962     printout
->SetPageSizeMM((int)mw
, (int)mh
); 
 963     printout
->OnPreparePrinting(); 
 965     // Get some parameters from the printout, if defined. 
 966     int fromPage
, toPage
; 
 967     int minPage
, maxPage
; 
 968     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 972         sm_lastError 
= wxPRINTER_ERROR
; 
 973         wxFAIL_MSG(_("wxPrintout::GetPageInfo gives a null maxPage.")); 
 977     printout
->OnBeginPrinting(); 
 981     // If we're not previewing we need to calculate the number of pages to print. 
 982     // If we're previewing, Gtk Print will render every pages without wondering about the page ranges the user may 
 983     // have defined in the dialog. So the number of pages is the maximum available. 
 984     if (!printout
->IsPreview()) 
 986         GtkPrintSettings 
* settings 
= gtk_print_operation_get_print_settings (operation
); 
 987         switch (gtk_print_settings_get_print_pages(settings
)) 
 989             case GTK_PRINT_PAGES_CURRENT
: 
 992             case GTK_PRINT_PAGES_RANGES
: 
 993                 {gint num_ranges 
= 0; 
 996                 range 
= gtk_print_settings_get_page_ranges (settings
, &num_ranges
); 
 997                 for (i
=0; i
<num_ranges
; i
++) 
 999                     if (range
[i
].end 
< range
[i
].start
) range
[i
].end 
= range
[i
].start
; 
1000                     if (range
[i
].start 
< minPage
-1) range
[i
].start 
= minPage
-1; 
1001                     if (range
[i
].end 
> maxPage
-1) range
[i
].end 
= maxPage
-1; 
1002                     if (range
[i
].start 
> maxPage
-1) range
[i
].start 
= maxPage
-1; 
1003                     numPages 
+= range
[i
].end 
- range
[i
].start 
+ 1; 
1005                 gtk_print_settings_set_page_ranges (settings
, range
, 1); 
1007             case GTK_PRINT_PAGES_ALL
: 
1009                 numPages 
= maxPage 
- minPage 
+ 1; 
1013     else numPages 
= maxPage 
- minPage 
+ 1; 
1015     gtk_print_operation_set_n_pages(operation
, numPages
); 
1018 void wxGtkPrinter::DrawPage(wxPrintout 
*printout
, 
1019                             GtkPrintOperation 
*operation
, 
1020                             GtkPrintContext 
* WXUNUSED(context
), 
1023     int fromPage
, toPage
, minPage
, maxPage
, startPage
, endPage
; 
1024     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
1026     int numPageToDraw 
= page_nr 
+ minPage
; 
1027     if (numPageToDraw 
< minPage
) numPageToDraw 
= minPage
; 
1028     if (numPageToDraw 
> maxPage
) numPageToDraw 
= maxPage
; 
1030     GtkPrintSettings 
* settings 
= gtk_print_operation_get_print_settings (operation
); 
1031     switch (gtk_print_settings_get_print_pages(settings
)) 
1033         case GTK_PRINT_PAGES_CURRENT
: 
1034             g_object_get_property((GObject
*) operation
, (const gchar 
*) "current-page", (GValue
*) &startPage
); 
1035             g_object_get_property((GObject
*) operation
, (const gchar 
*) "current-page", (GValue
*) &endPage
); 
1037         case GTK_PRINT_PAGES_RANGES
: 
1038             {gint num_ranges 
= 0; 
1039             GtkPageRange
* range
; 
1040             range 
= gtk_print_settings_get_page_ranges (settings
, &num_ranges
); 
1041             // We don't need to verify these values as it has already been done in wxGtkPrinter::BeginPrint. 
1042             if (num_ranges 
>= 1) 
1044                 startPage 
= range
[0].start 
+ 1; 
1045                 endPage 
= range
[0].end 
+ 1; 
1048                 startPage 
= minPage
; 
1052         case GTK_PRINT_PAGES_ALL
: 
1054             startPage 
= minPage
; 
1059     if(numPageToDraw 
== startPage
) 
1061         if (!printout
->OnBeginDocument(startPage
, endPage
)) 
1063             wxLogError(_("Could not start printing.")); 
1064             sm_lastError 
= wxPRINTER_ERROR
; 
1068     // The app can render the page numPageToDraw. 
1069     if (printout
->HasPage(numPageToDraw
)) 
1072         printout
->OnPrintPage(numPageToDraw
); 
1077     if(numPageToDraw 
== endPage
) 
1079         printout
->OnEndDocument(); 
1083 wxDC
* wxGtkPrinter::PrintDialog( wxWindow 
*parent 
) 
1085     wxGtkPrintDialog 
dialog( parent
, &m_printDialogData 
); 
1087     dialog
.SetPrintDC(m_dc
); 
1088     dialog
.SetShowDialog(true); 
1090     int ret 
= dialog
.ShowModal(); 
1092     if (ret 
== wxID_CANCEL
) 
1094         sm_lastError 
= wxPRINTER_CANCELLED
; 
1099         sm_lastError 
= wxPRINTER_ERROR
; 
1100         wxFAIL_MSG(_("The print dialog returned an error.")); 
1104     m_printDialogData 
= dialog
.GetPrintDialogData(); 
1106     return new wxPrinterDC( m_printDialogData
.GetPrintData() ); 
1109 bool wxGtkPrinter::Setup( wxWindow 
* WXUNUSED(parent
) ) 
1111     // Obsolete, for backward compatibility. 
1115 //----------------------------------------------------------------------------- 
1117 //----------------------------------------------------------------------------- 
1119 #define wxCAIRO_SCALE 1 
1123 #define XLOG2DEV(x)     LogicalToDeviceX(x) 
1124 #define XLOG2DEVREL(x)  LogicalToDeviceXRel(x) 
1125 #define YLOG2DEV(x)     LogicalToDeviceY(x) 
1126 #define YLOG2DEVREL(x)  LogicalToDeviceYRel(x) 
1130 #define XLOG2DEV(x)     ((double)(LogicalToDeviceX(x)) * m_DEV2PS) 
1131 #define XLOG2DEVREL(x)  ((double)(LogicalToDeviceXRel(x)) * m_DEV2PS) 
1132 #define YLOG2DEV(x)     ((double)(LogicalToDeviceY(x)) * m_DEV2PS) 
1133 #define YLOG2DEVREL(x)  ((double)(LogicalToDeviceYRel(x)) * m_DEV2PS) 
1137 IMPLEMENT_ABSTRACT_CLASS(wxGtkPrinterDCImpl
, wxDCImpl
) 
1139 wxGtkPrinterDCImpl::wxGtkPrinterDCImpl(wxPrinterDC 
*owner
, const wxPrintData
& data
) 
1144     wxGtkPrintNativeData 
*native 
= 
1145         (wxGtkPrintNativeData
*) m_printData
.GetNativeData(); 
1147     m_gpc 
= native
->GetPrintContext(); 
1149     // Match print quality to resolution (high = 1200dpi) 
1150     m_resolution 
= m_printData
.GetQuality(); // (int) gtk_print_context_get_dpi_x( m_gpc ); 
1151     if (m_resolution 
< 0) 
1152         m_resolution 
= (1 << (m_resolution
+4)) *150; 
1154     m_context 
= gtk_print_context_create_pango_context( m_gpc 
); 
1155     m_layout 
= gtk_print_context_create_pango_layout ( m_gpc 
); 
1156     m_fontdesc 
= pango_font_description_from_string( "Sans 12" ); 
1158     m_cairo 
= gtk_print_context_get_cairo_context ( m_gpc 
); 
1164     cairo_scale( m_cairo
, 72.0 / (double)m_resolution
, 72.0 / (double)m_resolution 
); 
1166     m_PS2DEV 
= (double)m_resolution 
/ 72.0; 
1167     m_DEV2PS 
= 72.0 / (double)m_resolution
; 
1174     m_signX 
= 1;  // default x-axis left to right. 
1175     m_signY 
= 1;  // default y-axis bottom up -> top down. 
1177     // By default the origin of the Cairo context is in the upper left 
1178     // corner of the printable area. We need to translate it so that it 
1179     // is in the upper left corner of the paper (without margins) 
1180     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
1182     ml 
= gtk_page_setup_get_left_margin (setup
, GTK_UNIT_POINTS
); 
1183     mt 
= gtk_page_setup_get_top_margin (setup
, GTK_UNIT_POINTS
); 
1184     cairo_translate(m_cairo
, -ml
, -mt
); 
1187 wxGtkPrinterDCImpl::~wxGtkPrinterDCImpl() 
1189     g_object_unref(m_context
); 
1190     g_object_unref(m_layout
); 
1193 bool wxGtkPrinterDCImpl::IsOk() const 
1195     return m_gpc 
!= NULL
; 
1198 void* wxGtkPrinterDCImpl::GetCairoContext() const 
1200     return (void*) cairo_reference( m_cairo 
); 
1203 bool wxGtkPrinterDCImpl::DoFloodFill(wxCoord 
WXUNUSED(x1
), 
1204                                wxCoord 
WXUNUSED(y1
), 
1205                                const wxColour
& WXUNUSED(col
), 
1206                                wxFloodFillStyle 
WXUNUSED(style
)) 
1208     // We can't access the given coord as a Cairo context is scalable, ie a 
1209     // coord doesn't mean anything in this context. 
1210     wxFAIL_MSG(_("not implemented")); 
1214 void wxGtkPrinterDCImpl::DoGradientFillConcentric(const wxRect
& rect
, const wxColour
& initialColour
, const wxColour
& destColour
, const wxPoint
& circleCenter
) 
1216     wxCoord xC 
= circleCenter
.x
; 
1217     wxCoord yC 
= circleCenter
.y
; 
1218     wxCoord xR 
= rect
.x
; 
1219     wxCoord yR 
= rect
.y
; 
1220     wxCoord w 
=  rect
.width
; 
1221     wxCoord h 
= rect
.height
; 
1223     const double r2 
= (w
/2)*(w
/2)+(h
/2)*(h
/2); 
1224     double radius 
= sqrt(r2
); 
1226     unsigned char redI 
= initialColour
.Red(); 
1227     unsigned char blueI 
= initialColour
.Blue(); 
1228     unsigned char greenI 
= initialColour
.Green(); 
1229     unsigned char alphaI 
= initialColour
.Alpha(); 
1230     unsigned char redD 
= destColour
.Red(); 
1231     unsigned char blueD 
= destColour
.Blue(); 
1232     unsigned char greenD 
= destColour
.Green(); 
1233     unsigned char alphaD 
= destColour
.Alpha(); 
1235     double redIPS 
= (double)(redI
) / 255.0; 
1236     double blueIPS 
= (double)(blueI
) / 255.0; 
1237     double greenIPS 
= (double)(greenI
) / 255.0; 
1238     double alphaIPS 
= (double)(alphaI
) / 255.0; 
1239     double redDPS 
= (double)(redD
) / 255.0; 
1240     double blueDPS 
= (double)(blueD
) / 255.0; 
1241     double greenDPS 
= (double)(greenD
) / 255.0; 
1242     double alphaDPS 
= (double)(alphaD
) / 255.0; 
1244     // Create a pattern with the gradient. 
1245     cairo_pattern_t
* gradient
; 
1246     gradient 
= cairo_pattern_create_radial (XLOG2DEV(xC
+xR
), YLOG2DEV(yC
+yR
), 0, XLOG2DEV(xC
+xR
), YLOG2DEV(yC
+yR
), radius 
* m_DEV2PS 
); 
1247     cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1248     cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1250     // Fill the rectangle with this pattern. 
1251     cairo_set_source(m_cairo
, gradient
); 
1252     cairo_rectangle (m_cairo
, XLOG2DEV(xR
), YLOG2DEV(yR
), XLOG2DEVREL(w
), YLOG2DEVREL(h
) ); 
1253     cairo_fill(m_cairo
); 
1255     cairo_pattern_destroy(gradient
); 
1257     CalcBoundingBox(xR
, yR
); 
1258     CalcBoundingBox(xR
+w
, yR
+h
); 
1261 void wxGtkPrinterDCImpl::DoGradientFillLinear(const wxRect
& rect
, const wxColour
& initialColour
, const wxColour
& destColour
, wxDirection nDirection
) 
1265     wxCoord w 
= rect
.width
; 
1266     wxCoord h 
= rect
.height
; 
1268     unsigned char redI 
= initialColour
.Red(); 
1269     unsigned char blueI 
= initialColour
.Blue(); 
1270     unsigned char greenI 
= initialColour
.Green(); 
1271     unsigned char alphaI 
= initialColour
.Alpha(); 
1272     unsigned char redD 
= destColour
.Red(); 
1273     unsigned char blueD 
= destColour
.Blue(); 
1274     unsigned char greenD 
= destColour
.Green(); 
1275     unsigned char alphaD 
= destColour
.Alpha(); 
1277     double redIPS 
= (double)(redI
) / 255.0; 
1278     double blueIPS 
= (double)(blueI
) / 255.0; 
1279     double greenIPS 
= (double)(greenI
) / 255.0; 
1280     double alphaIPS 
= (double)(alphaI
) / 255.0; 
1281     double redDPS 
= (double)(redD
) / 255.0; 
1282     double blueDPS 
= (double)(blueD
) / 255.0; 
1283     double greenDPS 
= (double)(greenD
) / 255.0; 
1284     double alphaDPS 
= (double)(alphaD
) / 255.0; 
1286     // Create a pattern with the gradient. 
1287     cairo_pattern_t
* gradient
; 
1288     gradient 
= cairo_pattern_create_linear (XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x
+w
), YLOG2DEV(y
)); 
1290     if (nDirection 
== wxWEST
) 
1292         cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1293         cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1296         cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1297         cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1300     // Fill the rectangle with this pattern. 
1301     cairo_set_source(m_cairo
, gradient
); 
1302     cairo_rectangle (m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEVREL(w
), YLOG2DEVREL(h
) ); 
1303     cairo_fill(m_cairo
); 
1305     cairo_pattern_destroy(gradient
); 
1307     CalcBoundingBox(x
, y
); 
1308     CalcBoundingBox(x
+w
, y
+h
); 
1311 bool wxGtkPrinterDCImpl::DoGetPixel(wxCoord 
WXUNUSED(x1
), 
1312                               wxCoord 
WXUNUSED(y1
), 
1313                               wxColour 
* WXUNUSED(col
)) const 
1315     wxFAIL_MSG(_("not implemented")); 
1319 void wxGtkPrinterDCImpl::DoDrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
) 
1321     if ( m_pen
.IsTransparent() ) 
1325     cairo_move_to ( m_cairo
, XLOG2DEV(x1
), YLOG2DEV(y1
) ); 
1326     cairo_line_to ( m_cairo
, XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
1327     cairo_stroke ( m_cairo 
); 
1329     CalcBoundingBox( x1
, y1 
); 
1330     CalcBoundingBox( x2
, y2 
); 
1333 void wxGtkPrinterDCImpl::DoCrossHair(wxCoord x
, wxCoord y
) 
1340     cairo_move_to (m_cairo
, XLOG2DEV(x
), 0); 
1341     cairo_line_to (m_cairo
, XLOG2DEV(x
), YLOG2DEVREL(h
)); 
1342     cairo_move_to (m_cairo
, 0, YLOG2DEV(y
)); 
1343     cairo_line_to (m_cairo
, XLOG2DEVREL(w
), YLOG2DEV(y
)); 
1345     cairo_stroke (m_cairo
); 
1346     CalcBoundingBox( 0, 0 ); 
1347     CalcBoundingBox( w
, h 
); 
1350 void wxGtkPrinterDCImpl::DoDrawArc(wxCoord x1
,wxCoord y1
,wxCoord x2
,wxCoord y2
,wxCoord xc
,wxCoord yc
) 
1352     double dx 
= x1 
- xc
; 
1353     double dy 
= y1 
- yc
; 
1354     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
1356     double alpha1
, alpha2
; 
1357     if (x1 
== x2 
&& y1 
== y2
) 
1365         alpha1 
= alpha2 
= 0.0; 
1369         alpha1 
= (x1 
- xc 
== 0) ? 
1370             (y1 
- yc 
< 0) ? 90.0 : -90.0 : 
1371             atan2(double(y1
-yc
), double(x1
-xc
)) * RAD2DEG
; 
1372         alpha2 
= (x2 
- xc 
== 0) ? 
1373             (y2 
- yc 
< 0) ? 90.0 : -90.0 : 
1374             atan2(double(y2
-yc
), double(x2
-xc
)) * RAD2DEG
; 
1376         while (alpha1 
<= 0)   alpha1 
+= 360; 
1377         while (alpha2 
<= 0)   alpha2 
+= 360; // adjust angles to be between. 
1378         while (alpha1 
> 360)  alpha1 
-= 360; // 0 and 360 degree. 
1379         while (alpha2 
> 360)  alpha2 
-= 360; 
1385     cairo_new_path(m_cairo
); 
1387     cairo_arc_negative ( m_cairo
, XLOG2DEV(xc
), YLOG2DEV(yc
), XLOG2DEVREL((int)radius
), alpha1
, alpha2
); 
1388     cairo_line_to(m_cairo
, XLOG2DEV(xc
), YLOG2DEV(yc
)); 
1389     cairo_close_path (m_cairo
); 
1391     SetBrush( m_brush 
); 
1392     cairo_fill_preserve( m_cairo 
); 
1395     cairo_stroke( m_cairo 
); 
1397     CalcBoundingBox (x1
, y1
); 
1398     CalcBoundingBox (xc
, yc
); 
1399     CalcBoundingBox (x2
, y2
); 
1402 void wxGtkPrinterDCImpl::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
) 
1404     cairo_save( m_cairo 
); 
1406     cairo_new_path(m_cairo
); 
1408     cairo_translate( m_cairo
, XLOG2DEV((wxCoord
) (x 
+ w 
/ 2.)), XLOG2DEV((wxCoord
) (y 
+ h 
/ 2.)) ); 
1409     double scale 
= (double)YLOG2DEVREL(h
) / (double) XLOG2DEVREL(w
); 
1410     cairo_scale( m_cairo
, 1.0, scale 
); 
1412     cairo_arc_negative ( m_cairo
, 0, 0, XLOG2DEVREL(w
/2), -sa
*DEG2RAD
, -ea
*DEG2RAD
); 
1415     cairo_stroke_preserve( m_cairo 
); 
1417     cairo_line_to(m_cairo
, 0,0); 
1419     SetBrush( m_brush 
); 
1420     cairo_fill( m_cairo 
); 
1422     cairo_restore( m_cairo 
); 
1424     CalcBoundingBox( x
, y
); 
1425     CalcBoundingBox( x
+w
, y
+h 
); 
1428 void wxGtkPrinterDCImpl::DoDrawPoint(wxCoord x
, wxCoord y
) 
1430     if ( m_pen
.IsTransparent() ) 
1435     cairo_move_to ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1436     cairo_line_to ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1437     cairo_stroke ( m_cairo 
); 
1439     CalcBoundingBox( x
, y 
); 
1442 void wxGtkPrinterDCImpl::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
) 
1444     if ( m_pen
.IsTransparent() ) 
1453     for ( i 
=0; i
<n 
; i
++ ) 
1454         CalcBoundingBox( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
); 
1456     cairo_move_to ( m_cairo
, XLOG2DEV(points
[0].x
+xoffset
), YLOG2DEV(points
[0].y
+yoffset
) ); 
1458     for (i 
= 1; i 
< n
; i
++) 
1459         cairo_line_to ( m_cairo
, XLOG2DEV(points
[i
].x
+xoffset
), YLOG2DEV(points
[i
].y
+yoffset
) ); 
1461     cairo_stroke ( m_cairo
); 
1464 void wxGtkPrinterDCImpl::DoDrawPolygon(int n
, wxPoint points
[], 
1465                                        wxCoord xoffset
, wxCoord yoffset
, 
1466                                        wxPolygonFillMode fillStyle
) 
1470     cairo_save(m_cairo
); 
1471     if (fillStyle 
== wxWINDING_RULE
) 
1472         cairo_set_fill_rule( m_cairo
, CAIRO_FILL_RULE_WINDING
); 
1474         cairo_set_fill_rule( m_cairo
, CAIRO_FILL_RULE_EVEN_ODD
); 
1476     int x 
= points
[0].x 
+ xoffset
; 
1477     int y 
= points
[0].y 
+ yoffset
; 
1478     cairo_new_path(m_cairo
); 
1479     cairo_move_to( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1481     for (i 
= 1; i 
< n
; i
++) 
1483         int x 
= points
[i
].x 
+ xoffset
; 
1484         int y 
= points
[i
].y 
+ yoffset
; 
1485         cairo_line_to( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1487     cairo_close_path(m_cairo
); 
1489     SetBrush( m_brush 
); 
1490     cairo_fill_preserve( m_cairo 
); 
1493     cairo_stroke( m_cairo 
); 
1495     CalcBoundingBox( x
, y 
); 
1497     cairo_restore(m_cairo
); 
1500 void wxGtkPrinterDCImpl::DoDrawPolyPolygon(int n
, int count
[], wxPoint points
[], 
1501                                            wxCoord xoffset
, wxCoord yoffset
, 
1502                                            wxPolygonFillMode fillStyle
) 
1504     wxDCImpl::DoDrawPolyPolygon( n
, count
, points
, xoffset
, yoffset
, fillStyle 
); 
1507 void wxGtkPrinterDCImpl::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1512     cairo_new_path(m_cairo
); 
1513     cairo_rectangle ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
1515     SetBrush( m_brush 
); 
1516     cairo_fill_preserve( m_cairo 
); 
1519     cairo_stroke( m_cairo 
); 
1521     CalcBoundingBox( x
, y 
); 
1522     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1525 void wxGtkPrinterDCImpl::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
) 
1530     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
1532     wxCoord dd 
= 2 * (wxCoord
) radius
; 
1533     if (dd 
> width
) dd 
= width
; 
1534     if (dd 
> height
) dd 
= height
; 
1537     wxCoord rad 
= (wxCoord
) radius
; 
1539     cairo_new_path(m_cairo
); 
1540     cairo_move_to(m_cairo
,XLOG2DEV(x 
+ rad
),YLOG2DEV(y
)); 
1541     cairo_curve_to(m_cairo
, 
1542                                 XLOG2DEV(x 
+ rad
),YLOG2DEV(y
), 
1543                                 XLOG2DEV(x
),YLOG2DEV(y
), 
1544                                 XLOG2DEV(x
),YLOG2DEV(y 
+ rad
)); 
1545     cairo_line_to(m_cairo
,XLOG2DEV(x
),YLOG2DEV(y 
+ height 
- rad
)); 
1546     cairo_curve_to(m_cairo
, 
1547                                 XLOG2DEV(x
),YLOG2DEV(y 
+ height 
- rad
), 
1548                                 XLOG2DEV(x
),YLOG2DEV(y 
+ height
), 
1549                                 XLOG2DEV(x 
+ rad
),YLOG2DEV(y 
+ height
)); 
1550     cairo_line_to(m_cairo
,XLOG2DEV(x 
+ width 
- rad
),YLOG2DEV(y 
+ height
)); 
1551     cairo_curve_to(m_cairo
, 
1552                                 XLOG2DEV(x 
+ width 
- rad
),YLOG2DEV(y 
+ height
), 
1553                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ height
), 
1554                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ height 
- rad
)); 
1555     cairo_line_to(m_cairo
,XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ rad
)); 
1556     cairo_curve_to(m_cairo
, 
1557                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ rad
), 
1558                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y
), 
1559                                 XLOG2DEV(x 
+ width 
- rad
),YLOG2DEV(y
)); 
1560     cairo_line_to(m_cairo
,XLOG2DEV(x 
+ rad
),YLOG2DEV(y
)); 
1561     cairo_close_path(m_cairo
); 
1564     cairo_fill_preserve(m_cairo
); 
1567     cairo_stroke(m_cairo
); 
1569     CalcBoundingBox(x
,y
); 
1570     CalcBoundingBox(x
+width
,y
+height
); 
1573 void wxGtkPrinterDCImpl::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1578     cairo_save (m_cairo
); 
1580     cairo_new_path(m_cairo
); 
1582     cairo_translate (m_cairo
, XLOG2DEV((wxCoord
) (x 
+ width 
/ 2.)), YLOG2DEV((wxCoord
) (y 
+ height 
/ 2.))); 
1583     cairo_scale(m_cairo
, 1, (double)YLOG2DEVREL(height
)/(double)XLOG2DEVREL(width
)); 
1584     cairo_arc ( m_cairo
, 0, 0, XLOG2DEVREL(width
/2), 0, 2 * M_PI
); 
1586     SetBrush( m_brush 
); 
1587     cairo_fill_preserve( m_cairo 
); 
1590     cairo_stroke( m_cairo 
); 
1592     CalcBoundingBox( x
, y 
); 
1593     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1595     cairo_restore (m_cairo
); 
1599 void wxGtkPrinterDCImpl::DoDrawSpline(const wxPointList 
*points
) 
1603     double c
, d
, x1
, y1
, x2
, y2
, x3
, y3
; 
1606     wxPointList::compatibility_iterator node 
= points
->GetFirst(); 
1607     p 
= node
->GetData(); 
1611     node 
= node
->GetNext(); 
1612     p 
= node
->GetData(); 
1616          (double)(x1 
+ c
) / 2; 
1618          (double)(y1 
+ d
) / 2; 
1620     cairo_new_path( m_cairo 
); 
1621     cairo_move_to( m_cairo
, XLOG2DEV((wxCoord
)x1
), YLOG2DEV((wxCoord
)y1
) ); 
1622     cairo_line_to( m_cairo
, XLOG2DEV((wxCoord
)x3
), YLOG2DEV((wxCoord
)y3
) ); 
1624     CalcBoundingBox( (wxCoord
)x1
, (wxCoord
)y1 
); 
1625     CalcBoundingBox( (wxCoord
)x3
, (wxCoord
)y3 
); 
1627     node 
= node
->GetNext(); 
1630         q 
= node
->GetData(); 
1638         x3 
= (double)(x2 
+ c
) / 2; 
1639         y3 
= (double)(y2 
+ d
) / 2; 
1641         cairo_curve_to(m_cairo
, 
1642             XLOG2DEV((wxCoord
)x1
), YLOG2DEV((wxCoord
)y1
), 
1643             XLOG2DEV((wxCoord
)x2
), YLOG2DEV((wxCoord
)y2
), 
1644             XLOG2DEV((wxCoord
)x3
), YLOG2DEV((wxCoord
)y3
) ); 
1646         CalcBoundingBox( (wxCoord
)x1
, (wxCoord
)y1 
); 
1647         CalcBoundingBox( (wxCoord
)x3
, (wxCoord
)y3 
); 
1649         node 
= node
->GetNext(); 
1652     cairo_line_to ( m_cairo
, XLOG2DEV((wxCoord
)c
), YLOG2DEV((wxCoord
)d
) ); 
1654     cairo_stroke( m_cairo 
); 
1656 #endif // wxUSE_SPLINES 
1658 bool wxGtkPrinterDCImpl::DoBlit(wxCoord xdest
, wxCoord ydest
, 
1659                           wxCoord width
, wxCoord height
, 
1660                           wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, 
1661                           wxRasterOperationMode rop
, bool useMask
, 
1662                           wxCoord 
WXUNUSED_UNLESS_DEBUG(xsrcMask
), 
1663                           wxCoord 
WXUNUSED_UNLESS_DEBUG(ysrcMask
)) 
1665     wxASSERT_MSG( xsrcMask 
== wxDefaultCoord 
&& ysrcMask 
== wxDefaultCoord
, 
1666                   wxT("mask coordinates are not supported") ); 
1668     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1670     // Blit into a bitmap. 
1671     wxBitmap 
bitmap( width
, height 
); 
1673     memDC
.SelectObject(bitmap
); 
1674     memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
, rop
); 
1675     memDC
.SelectObject(wxNullBitmap
); 
1677     // Draw bitmap. scaling and positioning is done there. 
1678     GetOwner()->DrawBitmap( bitmap
, xdest
, ydest
, useMask 
); 
1683 void wxGtkPrinterDCImpl::DoDrawIcon( const wxIcon
& icon
, wxCoord x
, wxCoord y 
) 
1685     DoDrawBitmap( icon
, x
, y
, true ); 
1688 void wxGtkPrinterDCImpl::DoDrawBitmap( const wxBitmap
& bitmap
, wxCoord x
, wxCoord y
, bool useMask 
) 
1690     wxCHECK_RET( bitmap
.IsOk(), wxT("Invalid bitmap in wxGtkPrinterDCImpl::DoDrawBitmap")); 
1692     x 
= wxCoord(XLOG2DEV(x
)); 
1693     y 
= wxCoord(YLOG2DEV(y
)); 
1694     int bw 
= bitmap
.GetWidth(); 
1695     int bh 
= bitmap
.GetHeight(); 
1696     wxBitmap bmpSource 
= bitmap
;  // we need a non-const instance. 
1697     if (!useMask 
&& !bitmap
.HasPixbuf() && bitmap
.GetMask()) 
1698         bmpSource
.SetMask(NULL
); 
1700     cairo_save(m_cairo
); 
1702     // Prepare to draw the image. 
1703     cairo_translate(m_cairo
, x
, y
); 
1706     wxDouble scaleX 
= (wxDouble
) XLOG2DEVREL(bw
) / (wxDouble
) bw
; 
1707     wxDouble scaleY 
= (wxDouble
) YLOG2DEVREL(bh
) / (wxDouble
) bh
; 
1708     cairo_scale(m_cairo
, scaleX
, scaleY
); 
1710     gdk_cairo_set_source_pixbuf(m_cairo
, bmpSource
.GetPixbuf(), 0, 0); 
1711     cairo_pattern_set_filter(cairo_get_source(m_cairo
), CAIRO_FILTER_NEAREST
); 
1712     // Use the original size here since the context is scaled already. 
1713     cairo_rectangle(m_cairo
, 0, 0, bw
, bh
); 
1714     // Fill the rectangle using the pattern. 
1715     cairo_fill(m_cairo
); 
1717     CalcBoundingBox(0,0); 
1718     CalcBoundingBox(bw
,bh
); 
1720     cairo_restore(m_cairo
); 
1723 void wxGtkPrinterDCImpl::DoDrawText(const wxString
& text
, wxCoord x
, wxCoord y 
) 
1725     DoDrawRotatedText( text
, x
, y
, 0.0 ); 
1728 void wxGtkPrinterDCImpl::DoDrawRotatedText(const wxString
& text
, wxCoord x
, wxCoord y
, double angle
) 
1730     double xx 
= XLOG2DEV(x
); 
1731     double yy 
= YLOG2DEV(y
); 
1735     bool underlined 
= m_font
.Ok() && m_font
.GetUnderlined(); 
1737     const wxScopedCharBuffer data 
= text
.utf8_str(); 
1739     size_t datalen 
= strlen(data
); 
1740     pango_layout_set_text( m_layout
, data
, datalen
); 
1744         PangoAttrList 
*attrs 
= pango_attr_list_new(); 
1745         PangoAttribute 
*a 
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
); 
1747         a
->end_index 
= datalen
; 
1748         pango_attr_list_insert(attrs
, a
); 
1749         pango_layout_set_attributes(m_layout
, attrs
); 
1750         pango_attr_list_unref(attrs
); 
1753     if (m_textForegroundColour
.Ok()) 
1755         unsigned char red 
= m_textForegroundColour
.Red(); 
1756         unsigned char blue 
= m_textForegroundColour
.Blue(); 
1757         unsigned char green 
= m_textForegroundColour
.Green(); 
1758         unsigned char alpha 
= m_textForegroundColour
.Alpha(); 
1760         if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1762             double redPS 
= (double)(red
) / 255.0; 
1763             double bluePS 
= (double)(blue
) / 255.0; 
1764             double greenPS 
= (double)(green
) / 255.0; 
1765             double alphaPS 
= (double)(alpha
) / 255.0; 
1767             cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1770             m_currentBlue 
= blue
; 
1771             m_currentGreen 
= green
; 
1772             m_currentAlpha 
= alpha
; 
1777     cairo_move_to (m_cairo
, xx
, yy
); 
1779     cairo_save( m_cairo 
); 
1781     if (fabs(angle
) > 0.00001) 
1782         cairo_rotate( m_cairo
, angle
*DEG2RAD 
); 
1784     cairo_scale(m_cairo
, m_scaleX
, m_scaleY
); 
1787     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1789     if ( m_backgroundMode 
== wxBRUSHSTYLE_SOLID 
) 
1791         unsigned char red 
= m_textBackgroundColour
.Red(); 
1792         unsigned char blue 
= m_textBackgroundColour
.Blue(); 
1793         unsigned char green 
= m_textBackgroundColour
.Green(); 
1794         unsigned char alpha 
= m_textBackgroundColour
.Alpha(); 
1796         double redPS 
= (double)(red
) / 255.0; 
1797         double bluePS 
= (double)(blue
) / 255.0; 
1798         double greenPS 
= (double)(green
) / 255.0; 
1799         double alphaPS 
= (double)(alpha
) / 255.0; 
1801         cairo_save(m_cairo
); 
1802         cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1803         cairo_rectangle(m_cairo
, 0, 0, w
, h
);   // still in cairo units 
1804         cairo_fill(m_cairo
); 
1805         cairo_restore(m_cairo
); 
1808     pango_cairo_update_layout (m_cairo
, m_layout
); 
1809     pango_cairo_show_layout (m_cairo
, m_layout
); 
1811     cairo_restore( m_cairo 
); 
1815         // Undo underline attributes setting 
1816         pango_layout_set_attributes(m_layout
, NULL
); 
1819     // Back to device units: 
1820     CalcBoundingBox (x
, y
); 
1821     CalcBoundingBox (x 
+ w
, y 
+ h
); 
1824 void wxGtkPrinterDCImpl::Clear() 
1826 // Clear does nothing for printing, but keep the code 
1829     cairo_save(m_cairo); 
1830     cairo_set_operator (m_cairo, CAIRO_OPERATOR_SOURCE); 
1831     SetBrush(m_backgroundBrush); 
1832     cairo_paint(m_cairo); 
1833     cairo_restore(m_cairo); 
1837 void wxGtkPrinterDCImpl::SetFont( const wxFont
& font 
) 
1844             pango_font_description_free( m_fontdesc 
); 
1846         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); 
1848         float size 
= pango_font_description_get_size( m_fontdesc 
); 
1849         size 
= size 
* GetFontPointSizeAdjustment(72.0); 
1850         pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1852         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1856 void wxGtkPrinterDCImpl::SetPen( const wxPen
& pen 
) 
1858     if (!pen
.Ok()) return; 
1864     if (m_pen
.GetWidth() <= 0) 
1867         width 
= (double) m_pen
.GetWidth(); 
1869     cairo_set_line_width( m_cairo
, width 
* m_DEV2PS 
* m_scaleX 
); 
1870     static const double dotted
[] = {2.0, 5.0}; 
1871     static const double short_dashed
[] = {4.0, 4.0}; 
1872     static const double long_dashed
[] = {4.0, 8.0}; 
1873     static const double dotted_dashed
[] = {6.0, 6.0, 2.0, 6.0}; 
1875     switch (m_pen
.GetStyle()) 
1877         case wxPENSTYLE_DOT
:        cairo_set_dash( m_cairo
, dotted
, 2, 0 ); break; 
1878         case wxPENSTYLE_SHORT_DASH
: cairo_set_dash( m_cairo
, short_dashed
, 2, 0 ); break; 
1879         case wxPENSTYLE_LONG_DASH
:  cairo_set_dash( m_cairo
, long_dashed
, 2, 0 ); break; 
1880         case wxPENSTYLE_DOT_DASH
:   cairo_set_dash( m_cairo
, dotted_dashed
, 4, 0 );  break; 
1881         case wxPENSTYLE_USER_DASH
: 
1884             int num 
= m_pen
.GetDashes (&wx_dashes
); 
1885             gdouble 
*g_dashes 
= g_new( gdouble
, num 
); 
1887             for (i 
= 0; i 
< num
; ++i
) 
1888                 g_dashes
[i
] = (gdouble
) wx_dashes
[i
]; 
1889             cairo_set_dash( m_cairo
, g_dashes
, num
, 0); 
1893         case wxPENSTYLE_SOLID
: 
1894         case wxPENSTYLE_TRANSPARENT
: 
1895         default:              cairo_set_dash( m_cairo
, NULL
, 0, 0 );   break; 
1898     switch (m_pen
.GetCap()) 
1900         case wxCAP_PROJECTING
:  cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_SQUARE
); break; 
1901         case wxCAP_BUTT
:        cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_BUTT
); break; 
1903         default:                cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_ROUND
); break; 
1906     switch (m_pen
.GetJoin()) 
1908         case wxJOIN_BEVEL
:  cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_BEVEL
); break; 
1909         case wxJOIN_MITER
:  cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_MITER
); break; 
1911         default:            cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_ROUND
); break; 
1914     unsigned char red 
= m_pen
.GetColour().Red(); 
1915     unsigned char blue 
= m_pen
.GetColour().Blue(); 
1916     unsigned char green 
= m_pen
.GetColour().Green(); 
1917     unsigned char alpha 
= m_pen
.GetColour().Alpha(); 
1919     if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1921         double redPS 
= (double)(red
) / 255.0; 
1922         double bluePS 
= (double)(blue
) / 255.0; 
1923         double greenPS 
= (double)(green
) / 255.0; 
1924         double alphaPS 
= (double)(alpha
) / 255.0; 
1926         cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1929         m_currentBlue 
= blue
; 
1930         m_currentGreen 
= green
; 
1931         m_currentAlpha 
= alpha
; 
1935 void wxGtkPrinterDCImpl::SetBrush( const wxBrush
& brush 
) 
1937     if (!brush
.Ok()) return; 
1941     if (m_brush
.GetStyle() == wxBRUSHSTYLE_TRANSPARENT
) 
1943         cairo_set_source_rgba( m_cairo
, 0, 0, 0, 0 ); 
1952     unsigned char red 
= m_brush
.GetColour().Red(); 
1953     unsigned char blue 
= m_brush
.GetColour().Blue(); 
1954     unsigned char green 
= m_brush
.GetColour().Green(); 
1955     unsigned char alpha 
= m_brush
.GetColour().Alpha(); 
1957     double redPS 
= (double)(red
) / 255.0; 
1958     double bluePS 
= (double)(blue
) / 255.0; 
1959     double greenPS 
= (double)(green
) / 255.0; 
1960     double alphaPS 
= (double)(alpha
) / 255.0; 
1962     if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1964         cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1967         m_currentBlue 
= blue
; 
1968         m_currentGreen 
= green
; 
1969         m_currentAlpha 
= alpha
; 
1972     if (m_brush
.IsHatch()) 
1975         cairo_surface_t 
*surface
; 
1976         surface 
= cairo_surface_create_similar(cairo_get_target(m_cairo
),CAIRO_CONTENT_COLOR_ALPHA
,10,10); 
1977         cr 
= cairo_create(surface
); 
1978         cairo_set_line_cap(cr
, CAIRO_LINE_CAP_SQUARE
); 
1979         cairo_set_line_width(cr
, 1); 
1980         cairo_set_line_join(cr
,CAIRO_LINE_JOIN_MITER
); 
1982         switch (m_brush
.GetStyle()) 
1984             case wxBRUSHSTYLE_CROSS_HATCH
: 
1985                 cairo_move_to(cr
, 5, 0); 
1986                 cairo_line_to(cr
, 5, 10); 
1987                 cairo_move_to(cr
, 0, 5); 
1988                 cairo_line_to(cr
, 10, 5); 
1990             case wxBRUSHSTYLE_BDIAGONAL_HATCH
: 
1991                 cairo_move_to(cr
, 0, 10); 
1992                 cairo_line_to(cr
, 10, 0); 
1994             case wxBRUSHSTYLE_FDIAGONAL_HATCH
: 
1995                 cairo_move_to(cr
, 0, 0); 
1996                 cairo_line_to(cr
, 10, 10); 
1998             case wxBRUSHSTYLE_CROSSDIAG_HATCH
: 
1999                 cairo_move_to(cr
, 0, 0); 
2000                 cairo_line_to(cr
, 10, 10); 
2001                 cairo_move_to(cr
, 10, 0); 
2002                 cairo_line_to(cr
, 0, 10); 
2004             case wxBRUSHSTYLE_HORIZONTAL_HATCH
: 
2005                 cairo_move_to(cr
, 0, 5); 
2006                 cairo_line_to(cr
, 10, 5); 
2008             case wxBRUSHSTYLE_VERTICAL_HATCH
: 
2009                 cairo_move_to(cr
, 5, 0); 
2010                 cairo_line_to(cr
, 5, 10); 
2013                 wxFAIL_MSG(_("Couldn't get hatch style from wxBrush.")); 
2016         cairo_set_source_rgba(cr
, redPS
, greenPS
, bluePS
, alphaPS
); 
2020         cairo_pattern_t 
* pattern 
= cairo_pattern_create_for_surface (surface
); 
2021         cairo_surface_destroy(surface
); 
2022         cairo_pattern_set_extend (pattern
, CAIRO_EXTEND_REPEAT
); 
2023         cairo_set_source(m_cairo
, pattern
); 
2024         cairo_pattern_destroy(pattern
); 
2028 void wxGtkPrinterDCImpl::SetLogicalFunction( wxRasterOperationMode function 
) 
2030     if (function 
== wxCLEAR
) 
2031         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_CLEAR
); 
2032     else if (function 
== wxOR
) 
2033         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_OUT
); 
2034     else if (function 
== wxNO_OP
) 
2035         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_DEST
); 
2036     else if (function 
== wxAND
) 
2037         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_ADD
); 
2038     else if (function 
== wxSET
) 
2039         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_SATURATE
); 
2040     else if (function 
== wxXOR
) 
2041         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_XOR
); 
2042     else // wxCOPY or anything else. 
2043         cairo_set_operator (m_cairo
, CAIRO_OPERATOR_SOURCE
); 
2046 void wxGtkPrinterDCImpl::SetBackground( const wxBrush
& brush 
) 
2048     m_backgroundBrush 
= brush
; 
2049     cairo_save(m_cairo
); 
2050     cairo_set_operator (m_cairo
, CAIRO_OPERATOR_DEST_OVER
); 
2052     SetBrush(m_backgroundBrush
); 
2053     cairo_paint(m_cairo
); 
2054     cairo_restore(m_cairo
); 
2057 void wxGtkPrinterDCImpl::SetBackgroundMode(int mode
) 
2059     if (mode 
== wxBRUSHSTYLE_SOLID
) 
2060         m_backgroundMode 
= wxBRUSHSTYLE_SOLID
; 
2062         m_backgroundMode 
= wxBRUSHSTYLE_TRANSPARENT
; 
2065 void wxGtkPrinterDCImpl::DoSetClippingRegion(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
2067     cairo_rectangle ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
2068     cairo_clip(m_cairo
); 
2071 void wxGtkPrinterDCImpl::DestroyClippingRegion() 
2073     cairo_reset_clip(m_cairo
); 
2076 bool wxGtkPrinterDCImpl::StartDoc(const wxString
& WXUNUSED(message
)) 
2081 void wxGtkPrinterDCImpl::EndDoc() 
2086 void wxGtkPrinterDCImpl::StartPage() 
2091 void wxGtkPrinterDCImpl::EndPage() 
2096 wxCoord 
wxGtkPrinterDCImpl::GetCharHeight() const 
2098     pango_layout_set_text( m_layout
, "H", 1 ); 
2101     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2103     return wxRound( h 
* m_PS2DEV 
); 
2106 wxCoord 
wxGtkPrinterDCImpl::GetCharWidth() const 
2108     pango_layout_set_text( m_layout
, "H", 1 ); 
2111     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2113     return wxRound( w 
* m_PS2DEV 
); 
2116 void wxGtkPrinterDCImpl::DoGetTextExtent(const wxString
& string
, wxCoord 
*width
, wxCoord 
*height
, 
2118                      wxCoord 
*externalLeading
, 
2119                      const wxFont 
*theFont 
) const 
2127     if ( externalLeading 
) 
2128         *externalLeading 
= 0; 
2135     cairo_save( m_cairo 
); 
2136     cairo_scale(m_cairo
, m_scaleX
, m_scaleY
); 
2138     // Set layout's text 
2139     const wxScopedCharBuffer dataUTF8 
= string
.utf8_str(); 
2144         // scale the font and apply it 
2145         PangoFontDescription 
*desc 
= theFont
->GetNativeFontInfo()->description
; 
2146         float size 
= pango_font_description_get_size(desc
); 
2147         size 
= size 
* GetFontPointSizeAdjustment(72.0); 
2148         pango_font_description_set_size(desc
, (gint
)size
); 
2150         pango_layout_set_font_description(m_layout
, desc
); 
2153     pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) ); 
2156     pango_layout_get_pixel_size( m_layout
, width
, &h 
); 
2162         PangoLayoutIter 
*iter 
= pango_layout_get_iter(m_layout
); 
2163         int baseline 
= pango_layout_iter_get_baseline(iter
); 
2164         pango_layout_iter_free(iter
); 
2165         *descent 
= h 
- PANGO_PIXELS(baseline
); 
2170         // restore font and reset font's size back 
2171         pango_layout_set_font_description(m_layout
, m_fontdesc
); 
2173         PangoFontDescription 
*desc 
= theFont
->GetNativeFontInfo()->description
; 
2174         pango_font_description_set_size(desc
, oldSize
); 
2177     cairo_restore( m_cairo 
); 
2180 void wxGtkPrinterDCImpl::DoGetSize(int* width
, int* height
) const 
2182     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
2185         *width 
= wxRound( (double)gtk_page_setup_get_paper_width( setup
, GTK_UNIT_POINTS 
) * (double)m_resolution 
/ 72.0 ); 
2187         *height 
= wxRound( (double)gtk_page_setup_get_paper_height( setup
, GTK_UNIT_POINTS 
) * (double)m_resolution 
/ 72.0 ); 
2190 void wxGtkPrinterDCImpl::DoGetSizeMM(int *width
, int *height
) const 
2192     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
2195         *width 
= wxRound( gtk_page_setup_get_paper_width( setup
, GTK_UNIT_MM 
) ); 
2197         *height 
= wxRound( gtk_page_setup_get_paper_height( setup
, GTK_UNIT_MM 
) ); 
2200 wxSize 
wxGtkPrinterDCImpl::GetPPI() const 
2202     return wxSize( (int)m_resolution
, (int)m_resolution 
); 
2205 void wxGtkPrinterDCImpl::SetPrintData(const wxPrintData
& data
) 
2210 // overriden for wxPrinterDC Impl 
2212 wxRect 
wxGtkPrinterDCImpl::GetPaperRect() const 
2214     // Does GtkPrint support printer margins? 
2217     DoGetSize( &w
, &h 
); 
2218     return wxRect( 0,0,w
,h 
); 
2221 int wxGtkPrinterDCImpl::GetResolution() const 
2223     return m_resolution
; 
2226 // ---------------------------------------------------------------------------- 
2228 // ---------------------------------------------------------------------------- 
2230 IMPLEMENT_CLASS(wxGtkPrintPreview
, wxPrintPreviewBase
) 
2232 void wxGtkPrintPreview::Init(wxPrintout 
* WXUNUSED(printout
), 
2233                              wxPrintout 
* WXUNUSED(printoutForPrinting
), 
2236     // convert wxPrintQuality to resolution (input pointer can be NULL) 
2237     wxPrintQuality quality 
= data 
? data
->GetQuality() : wxPRINT_QUALITY_MEDIUM
; 
2240         case wxPRINT_QUALITY_HIGH
: 
2241             m_resolution 
= 1200; 
2244         case wxPRINT_QUALITY_LOW
: 
2248         case wxPRINT_QUALITY_DRAFT
: 
2255                 // positive values directly indicate print resolution 
2256                 m_resolution 
= quality
; 
2260             wxFAIL_MSG( "unknown print quality" ); 
2263         case wxPRINT_QUALITY_MEDIUM
: 
2272 wxGtkPrintPreview::wxGtkPrintPreview(wxPrintout 
*printout
, 
2273                                      wxPrintout 
*printoutForPrinting
, 
2274                                      wxPrintDialogData 
*data
) 
2275                  : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
2277     Init(printout
, printoutForPrinting
, data 
? &data
->GetPrintData() : NULL
); 
2280 wxGtkPrintPreview::wxGtkPrintPreview(wxPrintout 
*printout
, 
2281                                      wxPrintout 
*printoutForPrinting
, 
2283                  : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
2285     Init(printout
, printoutForPrinting
, data
); 
2288 wxGtkPrintPreview::~wxGtkPrintPreview() 
2292 bool wxGtkPrintPreview::Print(bool interactive
) 
2294     if (!m_printPrintout
) 
2297     wxPrinter 
printer(& m_printDialogData
); 
2298     return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
); 
2301 void wxGtkPrintPreview::DetermineScaling() 
2303     wxPaperSize paperType 
= m_printDialogData
.GetPrintData().GetPaperId(); 
2305     wxPrintPaperType 
*paper 
= wxThePrintPaperDatabase
->FindPaperType(paperType
); 
2307         paper 
= wxThePrintPaperDatabase
->FindPaperType(wxPAPER_A4
); 
2311         m_previewPrintout
->SetPPIScreen(wxGetDisplayPPI()); 
2312         m_previewPrintout
->SetPPIPrinter( m_resolution
, m_resolution 
); 
2314         // Get width and height in points (1/72th of an inch) 
2315         wxSize 
sizeDevUnits(paper
->GetSizeDeviceUnits()); 
2316         sizeDevUnits
.x 
= wxRound((double)sizeDevUnits
.x 
* (double)m_resolution 
/ 72.0); 
2317         sizeDevUnits
.y 
= wxRound((double)sizeDevUnits
.y 
* (double)m_resolution 
/ 72.0); 
2319         wxSize 
sizeTenthsMM(paper
->GetSize()); 
2320         wxSize 
sizeMM(sizeTenthsMM
.x 
/ 10, sizeTenthsMM
.y 
/ 10); 
2322         // If in landscape mode, we need to swap the width and height. 
2323         if ( m_printDialogData
.GetPrintData().GetOrientation() == wxLANDSCAPE 
) 
2325             m_pageWidth 
= sizeDevUnits
.y
; 
2326             m_pageHeight 
= sizeDevUnits
.x
; 
2327             m_previewPrintout
->SetPageSizeMM(sizeMM
.y
, sizeMM
.x
); 
2331             m_pageWidth 
= sizeDevUnits
.x
; 
2332             m_pageHeight 
= sizeDevUnits
.y
; 
2333             m_previewPrintout
->SetPageSizeMM(sizeMM
.x
, sizeMM
.y
); 
2335         m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
); 
2336         m_previewPrintout
->SetPaperRectPixels(wxRect(0, 0, m_pageWidth
, m_pageHeight
)); 
2338         // At 100%, the page should look about page-size on the screen. 
2339         m_previewScaleX 
= 0.8 * 72.0 / (double)m_resolution
; 
2340         m_previewScaleY 
= m_previewScaleX
;