1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        wx/gtk/print.cpp 
   3 // Author:      Anthony Bretaudeau 
   4 // Purpose:     GTK printing support 
   6 // RCS-ID:      $Id: print.cpp,v 1 2007-08-25 05:44:44 PC Exp $ 
   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" 
  28 #include "wx/module.h" 
  31 #include "wx/fontutil.h" 
  32 #include "wx/gtk/private.h" 
  33 #include "wx/dynlib.h" 
  35 #include "wx/rawbmp.h" 
  38 #include <gtk/gtkpagesetupunixdialog.h> 
  41 wxFORCE_LINK_THIS_MODULE(gtk_print
) 
  43 #if wxUSE_LIBGNOMEPRINT 
  44 #include "wx/gtk/gnome/gprint.h" 
  47 // Usefull to convert angles from/to Rad to/from Deg. 
  48 static const double RAD2DEG  
= 180.0 / M_PI
; 
  49 static const double DEG2RAD  
= M_PI 
/ 180.0; 
  51 static wxCairoLibrary
* gs_cairo 
= NULL
; 
  53 //---------------------------------------------------------------------------- 
  55 // Initialized when starting the app : if it successfully load the gtk-print framework, 
  56 // it uses it. If not, it falls back to gnome print (see /gtk/gnome/gprint.cpp) then 
  57 // to postscript if gnomeprint is not available. 
  58 //---------------------------------------------------------------------------- 
  60 class wxGtkPrintModule
: public wxModule
 
  65 #if wxUSE_LIBGNOMEPRINT 
  66         // This module must be initialized AFTER gnomeprint's one 
  67         AddDependency(CLASSINFO(wxGnomePrintModule
)); 
  74     DECLARE_DYNAMIC_CLASS(wxGtkPrintModule
) 
  77 bool wxGtkPrintModule::OnInit() 
  79     gs_cairo 
= wxCairoLibrary::Get(); 
  80     if (gs_cairo 
&& gtk_check_version(2,10,0) == NULL
) 
  81         wxPrintFactory::SetPrintFactory( new wxGtkPrintFactory 
); 
  86 void wxGtkPrintModule::OnExit() 
  91 IMPLEMENT_DYNAMIC_CLASS(wxGtkPrintModule
, wxModule
) 
  93 //---------------------------------------------------------------------------- 
  95 //---------------------------------------------------------------------------- 
  97 wxPrinterBase
* wxGtkPrintFactory::CreatePrinter( wxPrintDialogData 
*data 
) 
  99     return new wxGtkPrinter( data 
); 
 102 wxPrintPreviewBase 
*wxGtkPrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 103                                                     wxPrintout 
*printout
, 
 104                                                     wxPrintDialogData 
*data 
) 
 106     return new wxGtkPrintPreview( preview
, printout
, data 
); 
 109 wxPrintPreviewBase 
*wxGtkPrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 110                                                     wxPrintout 
*printout
, 
 113     return new wxGtkPrintPreview( preview
, printout
, data 
); 
 116 wxPrintDialogBase 
*wxGtkPrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 117                                                   wxPrintDialogData 
*data 
) 
 119     return new wxGtkPrintDialog( parent
, data 
); 
 122 wxPrintDialogBase 
*wxGtkPrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 125     return new wxGtkPrintDialog( parent
, data 
); 
 128 wxPageSetupDialogBase 
*wxGtkPrintFactory::CreatePageSetupDialog( wxWindow 
*parent
, 
 129                                                           wxPageSetupDialogData 
* data 
) 
 131     return new wxGtkPageSetupDialog( parent
, data 
); 
 134 bool wxGtkPrintFactory::HasPrintSetupDialog() 
 139 wxDialog 
*wxGtkPrintFactory::CreatePrintSetupDialog( wxWindow 
*parent
, wxPrintData 
*data 
) 
 144 wxDC
* wxGtkPrintFactory::CreatePrinterDC( const wxPrintData
& data 
) 
 146     return new wxGtkPrintDC(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 objets to gtk printing callback functions. 
 189    wxGtkPrinter 
* printer
; 
 190    wxPrintout 
* printout
; 
 196     static void gtk_begin_print_callback (GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, gpointer user_data
) 
 198         wxPrinterToGtkData 
*data 
= (wxPrinterToGtkData 
*) user_data
; 
 200         data
->printer
->BeginPrint(data
->printout
, operation
, context
); 
 203     static void gtk_draw_page_print_callback (GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, gint page_nr
, gpointer user_data
) 
 205         wxPrinterToGtkData 
*data 
= (wxPrinterToGtkData 
*) user_data
; 
 207         data
->printer
->DrawPage(data
->printout
, operation
, context
, page_nr
); 
 210     static void gtk_end_print_callback (GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, gpointer user_data
) 
 212         wxPrintout 
*printout 
= (wxPrintout 
*) user_data
; 
 214         printout
->OnEndPrinting(); 
 217     static gboolean 
gtk_preview_print_callback (GtkPrintOperation 
*operation
, GtkPrintOperationPreview 
*preview
, GtkPrintContext 
*context
, GtkWindow 
*parent
, gpointer user_data
) 
 219         wxPrintout 
*printout 
= (wxPrintout 
*) user_data
; 
 221         printout
->SetIsPreview(true); 
 223         /* We create a cairo context with 72dpi resolution. This resolution is only used for positionning. */ 
 224         cairo_t 
*cairo 
= gdk_cairo_create(GTK_WIDGET(parent
)->window
); 
 225         gtk_print_context_set_cairo_context(context
, cairo
, 72, 72); 
 231 //---------------------------------------------------------------------------- 
 232 // wxGtkPrintNativeData 
 233 //---------------------------------------------------------------------------- 
 235 IMPLEMENT_CLASS(wxGtkPrintNativeData
, wxPrintNativeDataBase
) 
 237 wxGtkPrintNativeData::wxGtkPrintNativeData() 
 239     m_config 
= gtk_print_settings_new(); 
 242 wxGtkPrintNativeData::~wxGtkPrintNativeData() 
 244     g_object_unref (m_config
); 
 247 // Convert datas stored in m_config to a wxPrintData. 
 248 // Called by wxPrintData::ConvertFromNative(). 
 249 bool wxGtkPrintNativeData::TransferTo( wxPrintData 
&data 
) 
 254     GtkPrintQuality quality 
= gtk_print_settings_get_quality(m_config
); 
 255     if (quality 
== GTK_PRINT_QUALITY_HIGH
) 
 256         data
.SetQuality(wxPRINT_QUALITY_HIGH
); 
 257     else if (quality 
== GTK_PRINT_QUALITY_LOW
) 
 258         data
.SetQuality(wxPRINT_QUALITY_LOW
); 
 259     else if (quality 
== GTK_PRINT_QUALITY_DRAFT
) 
 260         data
.SetQuality(wxPRINT_QUALITY_DRAFT
); 
 262         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
); 
 398 // Put datas given by the wxPrintData into m_config. 
 399 // Called by wxPrintData::ConvertToNative(). 
 400 bool wxGtkPrintNativeData::TransferFrom( const wxPrintData 
&data 
) 
 405     wxPrintQuality quality 
= data
.GetQuality(); 
 406     if (quality 
== wxPRINT_QUALITY_HIGH
) 
 407         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_HIGH
); 
 408     else if (quality 
== wxPRINT_QUALITY_MEDIUM
) 
 409         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_NORMAL
); 
 410     else if (quality 
== wxPRINT_QUALITY_LOW
) 
 411         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_LOW
); 
 412     else if (quality 
== wxPRINT_QUALITY_DRAFT
) 
 413         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_DRAFT
); 
 414     else if (quality 
> 1) 
 415         gtk_print_settings_set_resolution (m_config
, quality
); 
 417         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_NORMAL
); 
 419     gtk_print_settings_set_n_copies(m_config
, data
.GetNoCopies()); 
 421     gtk_print_settings_set_use_color(m_config
, data
.GetColour()); 
 423     switch (data
.GetDuplex()) 
 425         case wxDUPLEX_SIMPLEX
:      gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_SIMPLEX
); 
 428         case wxDUPLEX_HORIZONTAL
:   gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_HORIZONTAL
); 
 432         case wxDUPLEX_VERTICAL
:      gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_VERTICAL
); 
 436     if (!data
.IsOrientationReversed()) 
 438         if (data
.GetOrientation() == wxLANDSCAPE
) 
 439             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_LANDSCAPE
); 
 441             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_PORTRAIT
); 
 444         if (data
.GetOrientation() == wxLANDSCAPE
) 
 445             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
); 
 447             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
); 
 450     gtk_print_settings_set_collate (m_config
, data
.GetCollate()); 
 452     // Paper formats: these are the most common paper formats. 
 453     switch (data
.GetPaperId()) 
 455         case wxPAPER_A3
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A3
)); 
 457         case wxPAPER_A4
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A4
)); 
 459         case wxPAPER_A5
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A5
)); 
 461         case wxPAPER_B5_TRANSVERSE
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "jis-b5")); 
 463         case wxPAPER_B5
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_B5
)); 
 465         case wxPAPER_LETTER
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_LETTER
)); 
 467         case wxPAPER_LEGAL
:     gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_LEGAL
)); 
 469         case wxPAPER_EXECUTIVE
: gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE
)); 
 471         case wxPAPER_ENV_10
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na_number-10")); 
 473         case wxPAPER_ENV_C5
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c5")); 
 475         case wxPAPER_ENV_C6
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c6")); 
 477         case wxPAPER_ENV_B5
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c5b5")); 
 479         case wxPAPER_ENV_MONARCH
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na_monarch")); 
 481         case wxPAPER_CSHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-c")); 
 483         case wxPAPER_DSHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-d")); 
 485         case wxPAPER_ESHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-e")); 
 487         case wxPAPER_LETTERSMALL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "letter")); 
 489         case wxPAPER_TABLOID
:   gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-b")); 
 491         case wxPAPER_LEDGER
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "ledger")); 
 493         case wxPAPER_STATEMENT
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "statement")); 
 495         case wxPAPER_A4SMALL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A4
)); 
 497         case wxPAPER_B4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b4")); 
 499         case wxPAPER_FOLIO
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "folio")); 
 501         case wxPAPER_QUARTO
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "quarto")); 
 503         case wxPAPER_10X14
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "10x14")); 
 505         case wxPAPER_11X17
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "ledger")); 
 507         case wxPAPER_NOTE
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "letter")); 
 509         case wxPAPER_ENV_9
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na-number-9-envelope")); 
 511         case wxPAPER_ENV_11
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-11")); 
 513         case wxPAPER_ENV_12
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-12")); 
 515         case wxPAPER_ENV_14
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-14")); 
 517         case wxPAPER_ENV_DL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-designated")); 
 519         case wxPAPER_ENV_C3
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c3")); 
 521         case wxPAPER_ENV_C4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c4")); 
 523         case wxPAPER_ENV_C65
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "c6/c5")); 
 525         case wxPAPER_ENV_B4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b4")); 
 527         case wxPAPER_ENV_B6
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b6")); 
 529         case wxPAPER_ENV_ITALY
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "Italian")); 
 531         case wxPAPER_ENV_PERSONAL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "personal")); 
 533         case wxPAPER_FANFOLD_US
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "fanfold-us")); 
 535         case wxPAPER_FANFOLD_STD_GERMAN
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "fanfold-European")); 
 537         case wxPAPER_FANFOLD_LGL_GERMAN
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "foolscap")); 
 546 void wxGtkPrintNativeData::SetPrintConfig( GtkPrintSettings 
* config 
) 
 549         m_config 
= gtk_print_settings_copy(config
); 
 552 // Extract page setup from settings. 
 553 GtkPageSetup
* wxGtkPrintNativeData::GetPageSetupFromSettings(GtkPrintSettings
* settings
) 
 555     GtkPageSetup
* page_setup 
= gtk_page_setup_new(); 
 556         gtk_page_setup_set_orientation (page_setup
, gtk_print_settings_get_orientation (settings
)); 
 558         GtkPaperSize 
*paper_size 
= gtk_print_settings_get_paper_size (settings
); 
 559         if (paper_size 
!= NULL
) 
 560                 gtk_page_setup_set_paper_size_and_default_margins (page_setup
, paper_size
); 
 565 // Insert page setup into a given GtkPrintSettings. 
 566 void wxGtkPrintNativeData::SetPageSetupToSettings(GtkPrintSettings
* settings
, GtkPageSetup
* page_setup
) 
 568     gtk_print_settings_set_orientation ( settings
, gtk_page_setup_get_orientation (page_setup
)); 
 569         gtk_print_settings_set_paper_size ( settings
, gtk_page_setup_get_paper_size (page_setup
)); 
 572 //---------------------------------------------------------------------------- 
 574 //---------------------------------------------------------------------------- 
 576 IMPLEMENT_CLASS(wxGtkPrintDialog
, wxPrintDialogBase
) 
 578 wxGtkPrintDialog::wxGtkPrintDialog( wxWindow 
*parent
, wxPrintDialogData 
*data 
) 
 579                     : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"), 
 580                                wxPoint(0, 0), wxSize(600, 600), 
 581                                wxDEFAULT_DIALOG_STYLE 
| 
 585         m_printDialogData 
= *data
; 
 591 wxGtkPrintDialog::wxGtkPrintDialog( wxWindow 
*parent
, wxPrintData 
*data 
) 
 592                     : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"), 
 593                                wxPoint(0, 0), wxSize(600, 600), 
 594                                wxDEFAULT_DIALOG_STYLE 
| 
 598         m_printDialogData 
= *data
; 
 605 wxGtkPrintDialog::~wxGtkPrintDialog() 
 609 // This is called even if we actually don't want the dialog to appear. 
 610 int wxGtkPrintDialog::ShowModal() 
 612     GtkPrintOperationResult response
; 
 614     // We need to restore the settings given in the constructor. 
 615     wxPrintData data 
= m_printDialogData
.GetPrintData(); 
 616     wxGtkPrintNativeData 
*native 
= 
 617       (wxGtkPrintNativeData
*) data
.GetNativeData(); 
 618     data
.ConvertToNative(); 
 620     GtkPrintSettings 
* settings 
= native
->GetPrintConfig(); 
 622     // We have to restore pages to print here because they're stored in a wxPrintDialogData and ConvertToNative only works for wxPrintData. 
 623     int fromPage 
= m_printDialogData
.GetFromPage(); 
 624     int toPage 
= m_printDialogData
.GetToPage(); 
 625     if (m_printDialogData
.GetSelection()) 
 626         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_CURRENT
); 
 627     else if (m_printDialogData
.GetAllPages()) 
 628         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_ALL
); 
 630         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_RANGES
); 
 632         range 
= g_new (GtkPageRange
, 1); 
 633         range
[0].start 
= fromPage
-1; 
 634         range
[0].end 
= (toPage 
>= fromPage
) ? toPage
-1 : fromPage
-1; 
 635         gtk_print_settings_set_page_ranges (settings
, range
, 1); 
 638     // If the settings are OK, we restore it. 
 639     if (settings 
!= NULL
) 
 640         gtk_print_operation_set_print_settings (native
->GetPrintJob(), settings
); 
 641         gtk_print_operation_set_default_page_setup (native
->GetPrintJob(), native
->GetPageSetupFromSettings(settings
)); 
 643     // Show the dialog if needed. 
 644     GError
* gError 
= NULL
; 
 646         response 
= gtk_print_operation_run (native
->GetPrintJob(), GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
, GTK_WINDOW(gtk_widget_get_toplevel(m_parent
->m_widget
) ), &gError
); 
 648         response 
= gtk_print_operation_run (native
->GetPrintJob(), GTK_PRINT_OPERATION_ACTION_PRINT
, (GtkWindow 
*) m_parent
, &gError
); 
 650     // Does everything went well? 
 651     if (response 
== GTK_PRINT_OPERATION_RESULT_CANCEL
) 
 655     else if (response 
== GTK_PRINT_OPERATION_RESULT_ERROR
) 
 657         g_error_free (gError
); 
 658         wxLogError(_("Error while printing: ") + wxString::Format(_("%s"), gError
->message
)); 
 659         return wxID_NO
; // We use wxID_NO because there is no wxID_ERROR available 
 662     // Now get the settings and save it. 
 663     GtkPrintSettings
* newSettings 
= gtk_print_operation_get_print_settings (native
->GetPrintJob()); 
 664     native
->SetPrintConfig(newSettings
); 
 665     data
.ConvertFromNative(); 
 667     // Same problem as a few lines before. 
 668     switch (gtk_print_settings_get_print_pages(newSettings
)) 
 670         case GTK_PRINT_PAGES_CURRENT
: 
 671             m_printDialogData
.SetSelection( true ); 
 673         case GTK_PRINT_PAGES_ALL
: 
 674             m_printDialogData
.SetAllPages( true ); 
 675             m_printDialogData
.SetFromPage( 0 ); 
 676             m_printDialogData
.SetToPage( 9999 ); 
 678         case GTK_PRINT_PAGES_RANGES
: 
 680             // wxWidgets doesn't support multiple ranges, so we can only save the first one even if the user wants to print others. 
 681             // 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 
 682             // will hit "OK" button. However we can only save 1-3 in the print data. 
 685             range 
= gtk_print_settings_get_page_ranges (newSettings
, &num_ranges
); 
 686             m_printDialogData
.SetFromPage( range
[0].start 
); 
 687             m_printDialogData
.SetToPage( range
[0].end 
); 
 694 //---------------------------------------------------------------------------- 
 695 // wxGtkPageSetupDialog 
 696 //---------------------------------------------------------------------------- 
 698 IMPLEMENT_CLASS(wxGtkPageSetupDialog
, wxPageSetupDialogBase
) 
 700 wxGtkPageSetupDialog::wxGtkPageSetupDialog( wxWindow 
*parent
, 
 701                             wxPageSetupDialogData
* data 
) 
 704         m_pageDialogData 
= *data
; 
 709 wxGtkPageSetupDialog::~wxGtkPageSetupDialog() 
 713 int wxGtkPageSetupDialog::ShowModal() 
 716     m_pageDialogData
.GetPrintData().ConvertToNative(); 
 717     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) m_pageDialogData
.GetPrintData().GetNativeData(); 
 718     GtkPrintSettings
* nativeData 
= native
->GetPrintConfig(); 
 720     // We only need the pagesetup data which are part of the settings. 
 721     GtkPageSetup
* oldPageSetup 
= native
->GetPageSetupFromSettings(nativeData
); 
 723     // If the user used a custom paper format the last time he printed, we have to restore it too. 
 724     if (m_pageDialogData
.GetPrintData().GetPaperId() == wxPAPER_NONE
) 
 726         wxSize customPaperSize 
= m_pageDialogData
.GetPaperSize(); 
 727         if (customPaperSize
.GetWidth() > 0 && customPaperSize
.GetHeight() > 0) 
 729             wxString title 
= _("Custom size"); 
 730             GtkPaperSize
* customSize 
= gtk_paper_size_new_custom ("custom", title
.mb_str(), (gdouble
) customPaperSize
.GetWidth(), (gdouble
) customPaperSize
.GetHeight(), GTK_UNIT_MM
); 
 731             gtk_page_setup_set_paper_size_and_default_margins (oldPageSetup
, customSize
); 
 732             g_object_unref(customSize
); 
 736     // Now show the dialog. 
 737     GtkPageSetup
* newPageSetup 
= gtk_print_run_page_setup_dialog (GTK_WINDOW(m_parent
->m_widget
), 
 742     if (newPageSetup 
!= oldPageSetup
) 
 744         native
->SetPageSetupToSettings(nativeData
, newPageSetup
); 
 745         m_pageDialogData
.GetPrintData().ConvertFromNative(); 
 747         // Store custom paper format if any. 
 748         if (m_pageDialogData
.GetPrintData().GetPaperId() == wxPAPER_NONE
) 
 750             gdouble ml
,mr
,mt
,mb
,pw
,ph
; 
 751             ml 
= gtk_page_setup_get_left_margin (newPageSetup
, GTK_UNIT_MM
); 
 752             mr 
= gtk_page_setup_get_right_margin (newPageSetup
, GTK_UNIT_MM
); 
 753             mt 
= gtk_page_setup_get_top_margin (newPageSetup
, GTK_UNIT_MM
); 
 754             mb 
= gtk_page_setup_get_bottom_margin (newPageSetup
, GTK_UNIT_MM
); 
 756             pw 
= gtk_page_setup_get_paper_width (newPageSetup
, GTK_UNIT_MM
); 
 757             ph 
= gtk_page_setup_get_paper_height (newPageSetup
, GTK_UNIT_MM
); 
 759             m_pageDialogData
.SetMarginTopLeft( wxPoint( (int)(ml
+0.5), (int)(mt
+0.5)) ); 
 760             m_pageDialogData
.SetMarginBottomRight( wxPoint( (int)(mr
+0.5), (int)(mb
+0.5)) ); 
 762             m_pageDialogData
.SetPaperSize( wxSize( (int)(pw
+0.5), (int)(ph
+0.5) ) ); 
 775 //---------------------------------------------------------------------------- 
 777 //---------------------------------------------------------------------------- 
 779 IMPLEMENT_CLASS(wxGtkPrinter
, wxPrinterBase
) 
 781 wxGtkPrinter::wxGtkPrinter( wxPrintDialogData 
*data 
) : 
 782     wxPrinterBase( data 
) 
 787         m_printDialogData 
= *data
; 
 790 wxGtkPrinter::~wxGtkPrinter() 
 794 bool wxGtkPrinter::Print(wxWindow 
*parent
, wxPrintout 
*printout
, bool prompt 
) 
 798         sm_lastError 
= wxPRINTER_ERROR
; 
 802     // Let's correct the PageInfo just in case the app gives wrong values. 
 803     int fromPage
, toPage
; 
 804     int minPage
, maxPage
; 
 805     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 806     m_printDialogData
.SetAllPages(true); 
 808     if (minPage 
< 1) minPage 
= 1; 
 809     if (maxPage 
< 1) maxPage 
= 9999; 
 810     if (maxPage 
< minPage
) maxPage 
= minPage
; 
 812     m_printDialogData
.SetMinPage(minPage
); 
 813     m_printDialogData
.SetMaxPage(maxPage
); 
 816         if (fromPage 
< minPage
) fromPage 
= minPage
; 
 817         else if (fromPage 
> maxPage
) fromPage 
= maxPage
; 
 818         m_printDialogData
.SetFromPage(fromPage
); 
 822         m_printDialogData
.SetToPage(toPage
); 
 823         if (toPage 
> maxPage
) toPage 
= maxPage
; 
 824         else if (toPage 
< minPage
) toPage 
= minPage
; 
 827     if (((minPage 
!= fromPage
) && fromPage 
!= 0) || ((maxPage 
!= toPage
) && toPage 
!= 0)) m_printDialogData
.SetAllPages(false); 
 830     wxPrintData printdata 
= GetPrintDialogData().GetPrintData(); 
 831     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) printdata
.GetNativeData(); 
 833     GtkPrintOperation 
*printOp 
= gtk_print_operation_new (); 
 835     native
->SetPrintJob( printOp 
); 
 837     printout
->SetIsPreview(false); 
 839     wxPrinterToGtkData dataToSend
; 
 840     dataToSend
.printer 
= this; 
 841     dataToSend
.printout 
= printout
; 
 843     // These Gtk signals are catched here. 
 844     g_signal_connect (printOp
, "begin-print", G_CALLBACK (gtk_begin_print_callback
), &dataToSend
); 
 845     g_signal_connect (printOp
, "draw-page", G_CALLBACK (gtk_draw_page_print_callback
), &dataToSend
); 
 846     g_signal_connect (printOp
, "end-print", G_CALLBACK (gtk_end_print_callback
), printout
); 
 847     g_signal_connect (printOp
, "preview", G_CALLBACK (gtk_preview_print_callback
), printout
); 
 851         m_showDialog 
= false; 
 853     // PrintDialog returns a wxDC but we created it before so we don't need it anymore: we just delete it. 
 854     wxDC
* uselessdc 
= PrintDialog( parent 
); 
 857     g_object_unref (printOp
); 
 859     return (sm_lastError 
== wxPRINTER_NO_ERROR
); 
 862 void wxGtkPrinter::BeginPrint(wxPrintout 
*printout
, GtkPrintOperation 
*operation
, GtkPrintContext 
*context
) 
 864     wxPrintData printdata 
= GetPrintDialogData().GetPrintData(); 
 865     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) printdata
.GetNativeData(); 
 867     SetPrintContext(context
); 
 868     native
->SetPrintContext( context 
); 
 870     wxGtkPrintDC 
*printDC 
= new wxGtkPrintDC( printdata 
); 
 875         if (sm_lastError 
!= wxPRINTER_CANCELLED
) 
 877             sm_lastError 
= wxPRINTER_ERROR
; 
 878             wxFAIL_MSG(_("The wxGtkPrintDC cannot be used.")); 
 882     wxSize ScreenPixels 
= wxGetDisplaySize(); 
 883     wxSize ScreenMM 
= wxGetDisplaySizeMM(); 
 885     printout
->SetPPIScreen( (int) ((ScreenPixels
.GetWidth() * 25.4) / ScreenMM
.GetWidth()), 
 886                             (int) ((ScreenPixels
.GetHeight() * 25.4) / ScreenMM
.GetHeight()) ); 
 887     printout
->SetPPIPrinter( printDC
->GetResolution(), 
 888                              printDC
->GetResolution() ); 
 890     printout
->SetDC(m_dc
); 
 893     m_dc
->GetSize(&w
, &h
); 
 894     printout
->SetPageSizePixels((int)w
, (int)h
); 
 895     printout
->SetPaperRectPixels(wxRect(0, 0, w
, h
)); 
 897     m_dc
->GetSizeMM(&mw
, &mh
); 
 898     printout
->SetPageSizeMM((int)mw
, (int)mh
); 
 899     printout
->OnPreparePrinting(); 
 901     // Get some parameters from the printout, if defined. 
 902     int fromPage
, toPage
; 
 903     int minPage
, maxPage
; 
 904     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 908         sm_lastError 
= wxPRINTER_ERROR
; 
 909         wxFAIL_MSG(_("wxPrintout::GetPageInfo gives a null maxPage.")); 
 913     printout
->OnBeginPrinting(); 
 917     // If we're not previewing we need to calculate the number of pages to print. 
 918     // If we're previewing, Gtk Print will render every pages without wondering about the page ranges the user may 
 919     // have defined in the dialog. So the number of pages is the maximum available. 
 920     if (!printout
->IsPreview()) 
 922         GtkPrintSettings 
* settings 
= gtk_print_operation_get_print_settings (operation
); 
 923         switch (gtk_print_settings_get_print_pages(settings
)) 
 925             case GTK_PRINT_PAGES_CURRENT
: 
 928             case GTK_PRINT_PAGES_RANGES
: 
 929                 {gint num_ranges 
= 0; 
 932                 range 
= gtk_print_settings_get_page_ranges (settings
, &num_ranges
); 
 933                 for (i
=0; i
<num_ranges
; i
++) 
 935                     if (range
[i
].end 
< range
[i
].start
) range
[i
].end 
= range
[i
].start
; 
 936                     if (range
[i
].start 
< minPage
-1) range
[i
].start 
= minPage
-1; 
 937                     if (range
[i
].end 
> maxPage
-1) range
[i
].end 
= maxPage
-1; 
 938                     if (range
[i
].start 
> maxPage
-1) range
[i
].start 
= maxPage
-1; 
 939                     numPages 
+= range
[i
].end 
- range
[i
].start 
+ 1; 
 941                 gtk_print_settings_set_page_ranges (settings
, range
, 1); 
 943             case GTK_PRINT_PAGES_ALL
: 
 945                 numPages 
= maxPage 
- minPage 
+ 1; 
 949     else numPages 
= maxPage 
- minPage 
+ 1; 
 951     gtk_print_operation_set_n_pages(operation
, numPages
); 
 954 void wxGtkPrinter::DrawPage(wxPrintout 
*printout
, GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, int page_nr
) 
 956     int fromPage
, toPage
, minPage
, maxPage
, startPage
, endPage
; 
 957     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 959     int numPageToDraw 
= page_nr 
+ minPage
; 
 960     if (numPageToDraw 
< minPage
) numPageToDraw 
= minPage
; 
 961     if (numPageToDraw 
> maxPage
) numPageToDraw 
= maxPage
; 
 963     GtkPrintSettings 
* settings 
= gtk_print_operation_get_print_settings (operation
); 
 964     switch (gtk_print_settings_get_print_pages(settings
)) 
 966         case GTK_PRINT_PAGES_CURRENT
: 
 967             g_object_get_property((GObject
*) operation
, (const gchar 
*) "current-page", (GValue
*) &startPage
); 
 968             g_object_get_property((GObject
*) operation
, (const gchar 
*) "current-page", (GValue
*) &endPage
); 
 970         case GTK_PRINT_PAGES_RANGES
: 
 971             {gint num_ranges 
= 0; 
 973             range 
= gtk_print_settings_get_page_ranges (settings
, &num_ranges
); 
 974             // We don't need to verify these values as it has already been done in wxGtkPrinter::BeginPrint. 
 975             startPage 
= range
[0].start 
+ 1; 
 976             endPage 
= range
[0].end 
+ 1; 
 978         case GTK_PRINT_PAGES_ALL
: 
 985     if(numPageToDraw 
== startPage
) 
 987         if (!printout
->OnBeginDocument(startPage
, endPage
)) 
 989             wxLogError(_("Could not start printing.")); 
 990             sm_lastError 
= wxPRINTER_ERROR
; 
 994     // The app can render the page numPageToDraw. 
 995     if (printout
->HasPage(numPageToDraw
)) 
 998         printout
->OnPrintPage(numPageToDraw
); 
1003     if(numPageToDraw 
== endPage
) 
1005         printout
->OnEndDocument(); 
1009 wxDC
* wxGtkPrinter::PrintDialog( wxWindow 
*parent 
) 
1011     wxGtkPrintDialog 
dialog( parent
, &m_printDialogData 
); 
1014     dialog
.SetPrintDC(m_dc
); 
1016     dialog
.SetShowDialog(m_showDialog
); 
1018     ret 
= dialog
.ShowModal(); 
1020     if (ret 
== wxID_CANCEL
) 
1022         sm_lastError 
= wxPRINTER_CANCELLED
; 
1027         sm_lastError 
= wxPRINTER_ERROR
; 
1028         wxFAIL_MSG(_("The print dialog returned an error.")); 
1032     m_printDialogData 
= dialog
.GetPrintDialogData(); 
1033     return new wxGtkPrintDC( m_printDialogData
.GetPrintData() ); 
1036 bool wxGtkPrinter::Setup( wxWindow 
*parent 
) 
1038     // Obsolete, for backward compatibility. 
1042 //----------------------------------------------------------------------------- 
1044 //----------------------------------------------------------------------------- 
1046 #define XLOG2DEV(x)     ((double)(LogicalToDeviceX(x)) * m_DEV2PS) 
1047 #define XLOG2DEVREL(x)  ((double)(LogicalToDeviceXRel(x)) * m_DEV2PS) 
1048 #define YLOG2DEV(x)     ((double)(LogicalToDeviceY(x)) * m_DEV2PS) 
1049 #define YLOG2DEVREL(x)  ((double)(LogicalToDeviceYRel(x)) * m_DEV2PS) 
1051 IMPLEMENT_CLASS(wxGtkPrintDC
, wxDC
) 
1053 wxGtkPrintDC::wxGtkPrintDC( const wxPrintData
& data 
) 
1057     wxGtkPrintNativeData 
*native 
= 
1058         (wxGtkPrintNativeData
*) m_printData
.GetNativeData(); 
1060     m_gpc 
= native
->GetPrintContext(); 
1062     // RR: what does this do? 
1063     m_resolution 
= m_printData
.GetQuality(); // (int) gtk_print_context_get_dpi_x( m_gpc ); 
1064     if (m_resolution 
< 0)  
1065         m_resolution 
= (1 << (m_resolution
+4)) *150; 
1067     wxPrintf( "resolution %d\n", m_resolution 
); 
1069     m_PS2DEV 
= (double)m_resolution 
/ 72.0; 
1070     m_DEV2PS 
= 72.0 / (double)m_resolution
; 
1072     m_context 
= gtk_print_context_create_pango_context( m_gpc 
); 
1073     m_layout 
= gtk_print_context_create_pango_layout ( m_gpc 
); 
1074     m_fontdesc 
= pango_font_description_from_string( "Sans 12" ); 
1076     m_cairo 
= gtk_print_context_get_cairo_context ( m_gpc 
); 
1082     m_signX 
=  1;  // default x-axis left to right. 
1083     m_signY 
= 1;  // default y-axis bottom up -> top down. 
1086 wxGtkPrintDC::~wxGtkPrintDC() 
1088     g_object_unref(m_context
); 
1089     g_object_unref(m_layout
); 
1092 bool wxGtkPrintDC::IsOk() const 
1094     return (m_gpc 
!= NULL
); 
1097 bool wxGtkPrintDC::DoFloodFill(wxCoord x1
, wxCoord y1
, const wxColour 
&col
, int style 
) 
1099     // We can't access the given coord as a cairo context is scalable, ie a coord doesn't mean anything in this context. 
1100     wxFAIL_MSG(_("not implemented")); 
1104 void wxGtkPrintDC::DoGradientFillConcentric(const wxRect
& rect
, const wxColour
& initialColour
, const wxColour
& destColour
, const wxPoint
& circleCenter
) 
1106     wxCoord xC 
= circleCenter
.x
; 
1107     wxCoord yC 
= circleCenter
.y
; 
1108     wxCoord xR 
= rect
.x
; 
1109     wxCoord yR 
= rect
.y
; 
1110     wxCoord w 
=  rect
.width
; 
1111     wxCoord h 
= rect
.height
; 
1113     double radius 
= sqrt((w
/2)*(w
/2)+(h
/2)*(h
/2)); 
1115     unsigned char redI 
= initialColour
.Red(); 
1116     unsigned char blueI 
= initialColour
.Blue(); 
1117     unsigned char greenI 
= initialColour
.Green(); 
1118     unsigned char alphaI 
= initialColour
.Alpha(); 
1119     unsigned char redD 
= destColour
.Red(); 
1120     unsigned char blueD 
= destColour
.Blue(); 
1121     unsigned char greenD 
= destColour
.Green(); 
1122     unsigned char alphaD 
= destColour
.Alpha(); 
1124     double redIPS 
= (double)(redI
) / 255.0; 
1125     double blueIPS 
= (double)(blueI
) / 255.0; 
1126     double greenIPS 
= (double)(greenI
) / 255.0; 
1127     double alphaIPS 
= (double)(alphaI
) / 255.0; 
1128     double redDPS 
= (double)(redD
) / 255.0; 
1129     double blueDPS 
= (double)(blueD
) / 255.0; 
1130     double greenDPS 
= (double)(greenD
) / 255.0; 
1131     double alphaDPS 
= (double)(alphaD
) / 255.0; 
1133     // Create a pattern with the gradient. 
1134     cairo_pattern_t
* gradient
; 
1135     gradient 
= gs_cairo
->cairo_pattern_create_radial (XLOG2DEV(xC
+xR
), YLOG2DEVREL(yC
+yR
), 0, XLOG2DEV(xC
+xR
), YLOG2DEVREL(yC
+yR
), radius 
* m_DEV2PS 
); 
1136     gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1137     gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1139     // Fill the rectangle with this pattern. 
1140     gs_cairo
->cairo_set_source(m_cairo
, gradient
); 
1141     gs_cairo
->cairo_rectangle (m_cairo
, XLOG2DEV(xR
), YLOG2DEVREL(yR
), XLOG2DEVREL(w
), YLOG2DEVREL(h
) ); 
1142     gs_cairo
->cairo_fill(m_cairo
); 
1144     gs_cairo
->cairo_pattern_destroy(gradient
); 
1146     CalcBoundingBox(xR
, yR
); 
1147     CalcBoundingBox(xR
+w
, yR
+h
); 
1150 void wxGtkPrintDC::DoGradientFillLinear(const wxRect
& rect
, const wxColour
& initialColour
, const wxColour
& destColour
, wxDirection nDirection
) 
1154     wxCoord w 
= rect
.width
; 
1155     wxCoord h 
= rect
.height
; 
1157     unsigned char redI 
= initialColour
.Red(); 
1158     unsigned char blueI 
= initialColour
.Blue(); 
1159     unsigned char greenI 
= initialColour
.Green(); 
1160     unsigned char alphaI 
= initialColour
.Alpha(); 
1161     unsigned char redD 
= destColour
.Red(); 
1162     unsigned char blueD 
= destColour
.Blue(); 
1163     unsigned char greenD 
= destColour
.Green(); 
1164     unsigned char alphaD 
= destColour
.Alpha(); 
1166     double redIPS 
= (double)(redI
) / 255.0; 
1167     double blueIPS 
= (double)(blueI
) / 255.0; 
1168     double greenIPS 
= (double)(greenI
) / 255.0; 
1169     double alphaIPS 
= (double)(alphaI
) / 255.0; 
1170     double redDPS 
= (double)(redD
) / 255.0; 
1171     double blueDPS 
= (double)(blueD
) / 255.0; 
1172     double greenDPS 
= (double)(greenD
) / 255.0; 
1173     double alphaDPS 
= (double)(alphaD
) / 255.0; 
1175     // Create a pattern with the gradient. 
1176     cairo_pattern_t
* gradient
; 
1177     gradient 
= gs_cairo
->cairo_pattern_create_linear (XLOG2DEVREL(x
), YLOG2DEVREL(y
), XLOG2DEVREL(x
+w
), YLOG2DEVREL(y
)); 
1179     if (nDirection 
== wxWEST
) 
1181         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1182         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1185         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1186         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1189     // Fill the rectangle with this pattern. 
1190     gs_cairo
->cairo_set_source(m_cairo
, gradient
); 
1191     gs_cairo
->cairo_rectangle (m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
), XLOG2DEVREL(w
), YLOG2DEVREL(h
) ); 
1192     gs_cairo
->cairo_fill(m_cairo
); 
1194     gs_cairo
->cairo_pattern_destroy(gradient
); 
1196     CalcBoundingBox(x
, y
); 
1197     CalcBoundingBox(x
+w
, y
+h
); 
1200 bool wxGtkPrintDC::DoGetPixel(wxCoord x1
, wxCoord y1
, wxColour 
*col
) const 
1202     // We can't access the given coord as a cairo context is scalable, ie a coord doesn't mean anything in this context. 
1203     wxFAIL_MSG(_("not implemented")); 
1207 void wxGtkPrintDC::DoDrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
) 
1209     if  (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
1212     gs_cairo
->cairo_move_to ( m_cairo
, XLOG2DEVREL(x1
), YLOG2DEVREL(y1
) ); 
1213     gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEVREL(x2
), YLOG2DEVREL(y2
) ); 
1214     gs_cairo
->cairo_stroke ( m_cairo 
); 
1216     CalcBoundingBox( x1
, y1 
); 
1217     CalcBoundingBox( x2
, y2 
); 
1220 void wxGtkPrintDC::DoCrossHair(wxCoord x
, wxCoord y
) 
1227     gs_cairo
->cairo_move_to (m_cairo
, XLOG2DEVREL(x
), 0); 
1228     gs_cairo
->cairo_line_to (m_cairo
, XLOG2DEVREL(x
), h 
* m_DEV2PS
); 
1229     gs_cairo
->cairo_move_to (m_cairo
, 0, YLOG2DEVREL(y
)); 
1230     gs_cairo
->cairo_line_to (m_cairo
, w 
* m_DEV2PS
, YLOG2DEVREL(y
)); 
1232     gs_cairo
->cairo_stroke (m_cairo
); 
1233     CalcBoundingBox( 0, 0 ); 
1234     CalcBoundingBox( w
, h 
); 
1237 void wxGtkPrintDC::DoDrawArc(wxCoord x1
,wxCoord y1
,wxCoord x2
,wxCoord y2
,wxCoord xc
,wxCoord yc
) 
1239     double dx 
= x1 
- xc
; 
1240     double dy 
= y1 
- yc
; 
1241     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
1243     double alpha1
, alpha2
; 
1244     if (x1 
== x2 
&& y1 
== y2
) 
1252         alpha1 
= alpha2 
= 0.0; 
1256         alpha1 
= (x1 
- xc 
== 0) ? 
1257             (y1 
- yc 
< 0) ? 90.0 : -90.0 : 
1258             atan2(double(y1
-yc
), double(x1
-xc
)) * RAD2DEG
; 
1259         alpha2 
= (x2 
- xc 
== 0) ? 
1260             (y2 
- yc 
< 0) ? 90.0 : -90.0 : 
1261             atan2(double(y2
-yc
), double(x2
-xc
)) * RAD2DEG
; 
1263         while (alpha1 
<= 0)   alpha1 
+= 360; 
1264         while (alpha2 
<= 0)   alpha2 
+= 360; // adjust angles to be between. 
1265         while (alpha1 
> 360)  alpha1 
-= 360; // 0 and 360 degree. 
1266         while (alpha2 
> 360)  alpha2 
-= 360; 
1272     gs_cairo
->cairo_arc_negative ( m_cairo
, XLOG2DEVREL(xc
), YLOG2DEVREL(yc
), XLOG2DEVREL((int)radius
), alpha1
, alpha2
); 
1273     gs_cairo
->cairo_line_to(m_cairo
, XLOG2DEVREL(xc
), YLOG2DEVREL(yc
)); 
1274     gs_cairo
->cairo_close_path (m_cairo
); 
1276     SetBrush( m_brush 
); 
1277     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1280     gs_cairo
->cairo_stroke( m_cairo 
); 
1282     CalcBoundingBox (x1
, y1
); 
1283     CalcBoundingBox (xc
, yc
); 
1284     CalcBoundingBox (x2
, y2
); 
1287 void wxGtkPrintDC::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
) 
1289     gs_cairo
->cairo_save( m_cairo 
); 
1291     gs_cairo
->cairo_translate( m_cairo
, XLOG2DEVREL((wxCoord
) (x 
+ w 
/ 2.)), XLOG2DEVREL((wxCoord
) (y 
+ h 
/ 2.)) ); 
1292     double scale 
= (double)YLOG2DEVREL(h
) / (double) XLOG2DEVREL(w
); 
1293     gs_cairo
->cairo_scale( m_cairo
, 1.0, scale 
); 
1295     gs_cairo
->cairo_arc_negative ( m_cairo
, 0, 0, XLOG2DEVREL(w
/2), -sa
*DEG2RAD
, -ea
*DEG2RAD
); 
1298     gs_cairo
->cairo_stroke_preserve( m_cairo 
); 
1300     gs_cairo
->cairo_line_to(m_cairo
, 0,0); 
1302     SetBrush( m_brush 
); 
1303     gs_cairo
->cairo_fill( m_cairo 
); 
1305     gs_cairo
->cairo_restore( m_cairo 
); 
1307     CalcBoundingBox( x
, y
); 
1308     CalcBoundingBox( x
+w
, y
+h 
); 
1311 void wxGtkPrintDC::DoDrawPoint(wxCoord x
, wxCoord y
) 
1313     if  (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
1317     gs_cairo
->cairo_move_to ( m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
) ); 
1318     gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
) ); 
1319     gs_cairo
->cairo_stroke ( m_cairo 
); 
1321     CalcBoundingBox( x
, y 
); 
1324 void wxGtkPrintDC::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
) 
1326     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
1333     for ( i 
=0; i
<n 
; i
++ ) 
1334         CalcBoundingBox( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
); 
1336     gs_cairo
->cairo_move_to ( m_cairo
, XLOG2DEVREL(points
[0].x
+xoffset
), YLOG2DEVREL(points
[0].y
+yoffset
) ); 
1338     for (i 
= 1; i 
< n
; i
++) 
1339         gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEVREL(points
[i
].x
+xoffset
), YLOG2DEVREL(points
[i
].y
+yoffset
) ); 
1341     gs_cairo
->cairo_stroke ( m_cairo
); 
1344 void wxGtkPrintDC::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
) 
1348     gs_cairo
->cairo_save(m_cairo
); 
1349     if (fillStyle 
== wxWINDING_RULE
) 
1350         gs_cairo
->cairo_set_fill_rule( m_cairo
, CAIRO_FILL_RULE_WINDING
); 
1352         gs_cairo
->cairo_set_fill_rule( m_cairo
, CAIRO_FILL_RULE_EVEN_ODD
); 
1354     int x 
= points
[0].x 
+ xoffset
; 
1355     int y 
= points
[0].y 
+ yoffset
; 
1356     gs_cairo
->cairo_new_path(m_cairo
); 
1357     gs_cairo
->cairo_move_to( m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
) ); 
1359     for (i 
= 1; i 
< n
; i
++) 
1361         int x 
= points
[i
].x 
+ xoffset
; 
1362         int y 
= points
[i
].y 
+ yoffset
; 
1363         gs_cairo
->cairo_line_to( m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
) ); 
1365     gs_cairo
->cairo_close_path(m_cairo
); 
1367     SetBrush( m_brush 
); 
1368     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1371     gs_cairo
->cairo_stroke( m_cairo 
); 
1373     CalcBoundingBox( x
, y 
); 
1375     gs_cairo
->cairo_restore(m_cairo
); 
1378 void wxGtkPrintDC::DoDrawPolyPolygon(int n
, int count
[], wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
) 
1380     wxDC::DoDrawPolyPolygon( n
, count
, points
, xoffset
, yoffset
, fillStyle 
); 
1383 void wxGtkPrintDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1385     gs_cairo
->cairo_rectangle ( m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
), XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
1387     SetBrush( m_brush 
); 
1388     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1391     gs_cairo
->cairo_stroke( m_cairo 
); 
1393     CalcBoundingBox( x
, y 
); 
1394     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1397 void wxGtkPrintDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
) 
1399     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
1401     wxCoord dd 
= 2 * (wxCoord
) radius
; 
1402     if (dd 
> width
) dd 
= width
; 
1403     if (dd 
> height
) dd 
= height
; 
1406     wxCoord rad 
= (wxCoord
) radius
; 
1408     gs_cairo
->cairo_new_path(m_cairo
); 
1409     gs_cairo
->cairo_move_to(m_cairo
,XLOG2DEVREL(x 
+ rad
),YLOG2DEVREL(y
)); 
1410     gs_cairo
->cairo_curve_to(m_cairo
, 
1411                                 XLOG2DEVREL(x 
+ rad
),YLOG2DEVREL(y
), 
1412                                 XLOG2DEVREL(x
),YLOG2DEVREL(y
), 
1413                                 XLOG2DEVREL(x
),YLOG2DEVREL(y 
+ rad
)); 
1414     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEVREL(x
),YLOG2DEVREL(y 
+ height 
- rad
)); 
1415     gs_cairo
->cairo_curve_to(m_cairo
, 
1416                                 XLOG2DEVREL(x
),YLOG2DEVREL(y 
+ height 
- rad
), 
1417                                 XLOG2DEVREL(x
),YLOG2DEVREL(y 
+ height
), 
1418                                 XLOG2DEVREL(x 
+ rad
),YLOG2DEVREL(y 
+ height
)); 
1419     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEVREL(x 
+ width 
- rad
),YLOG2DEVREL(y 
+ height
)); 
1420     gs_cairo
->cairo_curve_to(m_cairo
, 
1421                                 XLOG2DEVREL(x 
+ width 
- rad
),YLOG2DEVREL(y 
+ height
), 
1422                                 XLOG2DEVREL(x 
+ width
),YLOG2DEVREL(y 
+ height
), 
1423                                 XLOG2DEVREL(x 
+ width
),YLOG2DEVREL(y 
+ height 
- rad
)); 
1424     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEVREL(x 
+ width
),YLOG2DEVREL(y 
+ rad
)); 
1425     gs_cairo
->cairo_curve_to(m_cairo
, 
1426                                 XLOG2DEVREL(x 
+ width
),YLOG2DEVREL(y 
+ rad
), 
1427                                 XLOG2DEVREL(x 
+ width
),YLOG2DEVREL(y
), 
1428                                 XLOG2DEVREL(x 
+ width 
- rad
),YLOG2DEVREL(y
)); 
1429     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEVREL(x 
+ rad
),YLOG2DEVREL(y
)); 
1430     gs_cairo
->cairo_close_path(m_cairo
); 
1433     gs_cairo
->cairo_fill_preserve(m_cairo
); 
1436     gs_cairo
->cairo_stroke(m_cairo
); 
1438     CalcBoundingBox(x
,y
); 
1439     CalcBoundingBox(x
+width
,y
+height
); 
1442 void wxGtkPrintDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1444     gs_cairo
->cairo_save (m_cairo
); 
1446     gs_cairo
->cairo_translate (m_cairo
, XLOG2DEVREL((wxCoord
) (x 
+ width 
/ 2.)), YLOG2DEVREL((wxCoord
) (y 
+ height 
/ 2.))); 
1447     gs_cairo
->cairo_scale(m_cairo
, 1, (double)YLOG2DEVREL(height
)/(double)XLOG2DEVREL(width
)); 
1448     gs_cairo
->cairo_arc ( m_cairo
, 0, 0, XLOG2DEVREL(width
/2), 0, 2 * M_PI
); 
1450     SetBrush( m_brush 
); 
1451     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1454     gs_cairo
->cairo_stroke( m_cairo 
); 
1456     CalcBoundingBox( x
, y 
); 
1457     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1459     gs_cairo
->cairo_restore (m_cairo
); 
1463 void wxGtkPrintDC::DoDrawSpline(wxList 
*points
) 
1467     double c
, d
, x1
, y1
, x2
, y2
, x3
, y3
; 
1470     wxList::compatibility_iterator node 
= points
->GetFirst(); 
1471     p 
= (wxPoint 
*)node
->GetData(); 
1475     node 
= node
->GetNext(); 
1476     p 
= (wxPoint 
*)node
->GetData(); 
1480          (double)(x1 
+ c
) / 2; 
1482          (double)(y1 
+ d
) / 2; 
1484     gs_cairo
->cairo_new_path( m_cairo 
); 
1485     gs_cairo
->cairo_move_to( m_cairo
, XLOG2DEVREL((wxCoord
)x1
), YLOG2DEVREL((wxCoord
)y1
) ); 
1486     gs_cairo
->cairo_line_to( m_cairo
, XLOG2DEVREL((wxCoord
)x3
), YLOG2DEVREL((wxCoord
)y3
) ); 
1488     CalcBoundingBox( (wxCoord
)x1
, (wxCoord
)y1 
); 
1489     CalcBoundingBox( (wxCoord
)x3
, (wxCoord
)y3 
); 
1491     node 
= node
->GetNext(); 
1494         q 
= (wxPoint 
*)node
->GetData(); 
1502         x3 
= (double)(x2 
+ c
) / 2; 
1503         y3 
= (double)(y2 
+ d
) / 2; 
1505         gs_cairo
->cairo_curve_to(m_cairo
, 
1506             XLOG2DEVREL((wxCoord
)x1
), YLOG2DEVREL((wxCoord
)y1
), 
1507             XLOG2DEVREL((wxCoord
)x2
), YLOG2DEVREL((wxCoord
)y2
), 
1508             XLOG2DEVREL((wxCoord
)x3
), YLOG2DEVREL((wxCoord
)y3
) ); 
1510         CalcBoundingBox( (wxCoord
)x1
, (wxCoord
)y1 
); 
1511         CalcBoundingBox( (wxCoord
)x3
, (wxCoord
)y3 
); 
1513         node 
= node
->GetNext(); 
1516     gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEVREL((wxCoord
)c
), YLOG2DEVREL((wxCoord
)d
) ); 
1518     gs_cairo
->cairo_stroke( m_cairo 
); 
1520 #endif // wxUSE_SPLINES 
1522 bool wxGtkPrintDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
, 
1523             wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, int rop
, bool useMask
, 
1524             wxCoord xsrcMask
, wxCoord ysrcMask
) 
1526     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1528     // Blit into a bitmap. 
1529     wxBitmap 
bitmap( width
, height 
); 
1531     memDC
.SelectObject(bitmap
); 
1532     memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
, rop
); 
1533     memDC
.SelectObject(wxNullBitmap
); 
1535     // Draw bitmap. scaling and positioning is done there. 
1536     DrawBitmap( bitmap
, xdest
, ydest
, useMask 
); 
1541 void wxGtkPrintDC::DoDrawIcon( const wxIcon
& icon
, wxCoord x
, wxCoord y 
) 
1543     DoDrawBitmap( icon
, x
, y
, true ); 
1546 void wxGtkPrintDC::DoDrawBitmap( const wxBitmap
& bitmap
, wxCoord x
, wxCoord y
, bool useMask 
) 
1548     wxCHECK_RET( bitmap
.IsOk(), wxT("Invalid bitmap in wxGtkPrintDC::DoDrawBitmap")); 
1550     cairo_surface_t
* surface
; 
1551     x 
= wxCoord(XLOG2DEVREL(x
)); 
1552     y 
= wxCoord(YLOG2DEVREL(y
)); 
1553     int bw 
= bitmap
.GetWidth(); 
1554     int bh 
= bitmap
.GetHeight(); 
1555     wxBitmap bmpSource 
= bitmap
;  // we need a non-const instance. 
1556     unsigned char* buffer 
= new unsigned char[bw
*bh
*4]; 
1557     wxUint32
* data 
= (wxUint32
*)buffer
; 
1559     wxMask 
*mask 
= NULL
; 
1560     if (useMask
) mask 
= bmpSource
.GetMask(); 
1562     // Create a surface object and copy the bitmap pixel data to it. If the image has alpha (or a mask represented as alpha) 
1563     // then we'll use a different format and iterator than if it doesn't. 
1564     if (bmpSource
.HasAlpha() || mask
) 
1566         surface 
= gs_cairo
->cairo_image_surface_create_for_data( 
1567             buffer
, CAIRO_FORMAT_ARGB32
, bw
, bh
, bw
*4); 
1568         wxAlphaPixelData 
pixData(bmpSource
, wxPoint(0,0), wxSize(bw
, bh
)); 
1569         wxCHECK_RET( pixData
, wxT("Failed to gain raw access to bitmap data.")); 
1571         wxAlphaPixelData::Iterator 
p(pixData
); 
1573         for (y
=0; y
<bh
; y
++) 
1575             wxAlphaPixelData::Iterator rowStart 
= p
; 
1576             for (x
=0; x
<bw
; x
++) 
1578                 // Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity, 
1579                 // with alpha in the upper 8 bits, then red, then green, then 
1580                 // blue. The 32-bit quantities are stored native-endian. 
1581                 // Pre-multiplied alpha is used. 
1582                 unsigned char alpha 
= p
.Alpha(); 
1586                     *data 
= ( alpha
/255                  << 24 
1587                               | (p
.Red() * alpha
/255)    << 16 
1588                               | (p
.Green() * alpha
/255)  <<  8 
1589                               | (p
.Blue() * alpha
/255) ); 
1594             p
.OffsetY(pixData
, 1); 
1599         surface 
= gs_cairo
->cairo_image_surface_create_for_data( 
1600             buffer
, CAIRO_FORMAT_RGB24
, bw
, bh
, bw
*4); 
1601         wxNativePixelData 
pixData(bmpSource
, wxPoint(0,0), wxSize(bw
, bh
)); 
1602         wxCHECK_RET( pixData
, wxT("Failed to gain raw access to bitmap data.")); 
1604         wxNativePixelData::Iterator 
p(pixData
); 
1606         for (y
=0; y
<bh
; y
++) 
1608             wxNativePixelData::Iterator rowStart 
= p
; 
1609             for (x
=0; x
<bw
; x
++) 
1611                 // Each pixel in CAIRO_FORMAT_RGB24 is a 32-bit quantity, with 
1612                 // the upper 8 bits unused. Red, Green, and Blue are stored in 
1613                 // the remaining 24 bits in that order.  The 32-bit quantities 
1614                 // are stored native-endian. 
1615                 *data 
= ( p
.Red() << 16 | p
.Green() << 8 | p
.Blue() ); 
1620             p
.OffsetY(pixData
, 1); 
1625     gs_cairo
->cairo_save(m_cairo
); 
1626     // In case we're scaling the image by using a width and height different 
1627     // than the bitmap's size create a pattern transformation on the surface and 
1628     // draw the transformed pattern. 
1629     cairo_pattern_t
* pattern 
= gs_cairo
->cairo_pattern_create_for_surface(surface
); 
1631     // Prepare to draw the image. 
1632     gs_cairo
->cairo_translate(m_cairo
, x
, y
); 
1633     gs_cairo
->cairo_set_source(m_cairo
, pattern
); 
1634     // Use the original size here since the context is scaled already. 
1635     gs_cairo
->cairo_rectangle(m_cairo
, 0, 0, bw
, bh
); 
1636     // Fill the rectangle using the pattern. 
1637     gs_cairo
->cairo_fill(m_cairo
); 
1640     gs_cairo
->cairo_pattern_destroy(pattern
); 
1641     gs_cairo
->cairo_surface_destroy(surface
); 
1644     CalcBoundingBox(0,0); 
1645     CalcBoundingBox(bw
,bh
); 
1647     gs_cairo
->cairo_restore(m_cairo
); 
1650 void wxGtkPrintDC::DoDrawText(const wxString
& text
, wxCoord x
, wxCoord y 
) 
1652     DoDrawRotatedText( text
, x
, y
, 0.0 ); 
1655 void wxGtkPrintDC::DoDrawRotatedText(const wxString
& text
, wxCoord x
, wxCoord y
, double angle
) 
1657     double xx 
= XLOG2DEV(x
); 
1658     double yy 
= YLOG2DEV(y
); 
1662     bool underlined 
= m_font
.Ok() && m_font
.GetUnderlined(); 
1664 // FIXME-UTF8: wouldn't be needed if utf8_str() always returned a buffer 
1665 #if wxUSE_UNICODE_UTF8 
1666     const char *data 
= text
.utf8_str(); 
1668     const wxCharBuffer data 
= text
.utf8_str(); 
1671     size_t datalen 
= strlen(data
); 
1672     pango_layout_set_text( m_layout
, data
, datalen
); 
1676         PangoAttrList 
*attrs 
= pango_attr_list_new(); 
1677         PangoAttribute 
*a 
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
); 
1679         a
->end_index 
= datalen
; 
1680         pango_attr_list_insert(attrs
, a
); 
1681         pango_layout_set_attributes(m_layout
, attrs
); 
1682         pango_attr_list_unref(attrs
); 
1685     if (m_textForegroundColour
.Ok()) 
1687         unsigned char red 
= m_textForegroundColour
.Red(); 
1688         unsigned char blue 
= m_textForegroundColour
.Blue(); 
1689         unsigned char green 
= m_textForegroundColour
.Green(); 
1690         unsigned char alpha 
= m_textForegroundColour
.Alpha(); 
1692         if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1694             double redPS 
= (double)(red
) / 255.0; 
1695             double bluePS 
= (double)(blue
) / 255.0; 
1696             double greenPS 
= (double)(green
) / 255.0; 
1697             double alphaPS 
= (double)(alpha
) / 255.0; 
1699             gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1702             m_currentBlue 
= blue
; 
1703             m_currentGreen 
= green
; 
1704             m_currentAlpha 
= alpha
; 
1709     // TODO: steal scale implementation from GNOME print 
1712     pango_layout_get_pixel_size( m_layout
, &w
, &h 
);            // cairo units 
1714         if ( m_backgroundMode 
== wxSOLID 
) 
1716             unsigned char red 
= m_textBackgroundColour
.Red(); 
1717             unsigned char blue 
= m_textBackgroundColour
.Blue(); 
1718             unsigned char green 
= m_textBackgroundColour
.Green(); 
1719             unsigned char alpha 
= m_textBackgroundColour
.Alpha(); 
1721             double redPS 
= (double)(red
) / 255.0; 
1722             double bluePS 
= (double)(blue
) / 255.0; 
1723             double greenPS 
= (double)(green
) / 255.0; 
1724             double alphaPS 
= (double)(alpha
) / 255.0; 
1726             gs_cairo
->cairo_save(m_cairo
); 
1727             gs_cairo
->cairo_translate(m_cairo
, xx
, yy
); 
1728             gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1729             gs_cairo
->cairo_rotate(m_cairo
,angle
*DEG2RAD
); 
1730             gs_cairo
->cairo_rectangle(m_cairo
, 0, 0, w
, h
);   // still in cairo units 
1731             gs_cairo
->cairo_fill(m_cairo
); 
1732             gs_cairo
->cairo_restore(m_cairo
); 
1736     gs_cairo
->cairo_move_to (m_cairo
, xx
, yy
); 
1738     gs_cairo
->cairo_save( m_cairo 
); 
1740     gs_cairo
->cairo_scale( m_cairo
, m_scaleX
, m_scaleY 
); 
1742     if (fabs(angle
) > 0.00001) 
1743         gs_cairo
->cairo_rotate( m_cairo
, angle
*DEG2RAD 
); 
1745     gs_cairo
->pango_cairo_update_layout (m_cairo
, m_layout
); 
1746     gs_cairo
->pango_cairo_show_layout (m_cairo
, m_layout
); 
1748     gs_cairo
->cairo_restore( m_cairo 
); 
1752         // Undo underline attributes setting 
1753         pango_layout_set_attributes(m_layout
, NULL
); 
1756     // Back to device units: 
1757     CalcBoundingBox (x
, y
); 
1758     CalcBoundingBox (x 
+ w
, y 
+ h
); 
1761 void wxGtkPrintDC::Clear() 
1763 // Clear does nothing for printing, but keep the code 
1766     gs_cairo->cairo_save(m_cairo); 
1767     gs_cairo->cairo_set_operator (m_cairo, CAIRO_OPERATOR_SOURCE); 
1768     SetBrush(m_backgroundBrush); 
1769     gs_cairo->cairo_paint(m_cairo); 
1770     gs_cairo->cairo_restore(m_cairo); 
1774 void wxGtkPrintDC::SetFont( const wxFont
& font 
) 
1781             pango_font_description_free( m_fontdesc 
); 
1783         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); // m_fontdesc is now set to device units 
1785         // Scale font description from device units to pango units 
1786         gint oldSize 
= pango_font_description_get_size( m_fontdesc 
);  
1787         double size 
= oldSize 
*m_DEV2PS
;                          // scale to cairo units 
1788         pango_font_description_set_size( m_fontdesc
, (gint
)size 
);    // apply to description 
1790         // Actually apply scaled font. 
1791         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1795 void wxGtkPrintDC::SetPen( const wxPen
& pen 
) 
1797     if (!pen
.Ok()) return; 
1801     double width 
= (double) m_pen
.GetWidth(); 
1802     if (width 
== 0) width 
= 0.1; 
1804     gs_cairo
->cairo_set_line_width( m_cairo
, XLOG2DEVREL( (wxCoord
)((1000.0 * (double)width 
) / 1000.0)) ); 
1805     static const double dotted
[] = {2.0, 5.0}; 
1806     static const double short_dashed
[] = {4.0, 4.0}; 
1807     static const double long_dashed
[] = {4.0, 8.0}; 
1808     static const double dotted_dashed
[] = {6.0, 6.0, 2.0, 6.0}; 
1810     switch (m_pen
.GetStyle()) 
1812         case wxDOT
:           gs_cairo
->cairo_set_dash( m_cairo
, dotted
, 1, 0 ); break; 
1813         case wxSHORT_DASH
:    gs_cairo
->cairo_set_dash( m_cairo
, short_dashed
, 1, 0 ); break; 
1814         case wxLONG_DASH
:     gs_cairo
->cairo_set_dash( m_cairo
, long_dashed
, 1, 0 ); break; 
1815         case wxDOT_DASH
:      gs_cairo
->cairo_set_dash( m_cairo
, dotted_dashed
, 3, 0 );  break; 
1819             int num 
= m_pen
.GetDashes (&wx_dashes
) - 1; 
1820             gdouble 
*g_dashes 
= g_new( gdouble
, num 
); 
1822             for (i 
= 0; i 
< num
; ++i
) 
1823                 g_dashes
[i
] = (gdouble
) wx_dashes
[i
]; 
1824             gs_cairo
->cairo_set_dash( m_cairo
, g_dashes
, num
, 0); 
1830         default:              gs_cairo
->cairo_set_dash( m_cairo
, NULL
, 0, 0 );   break; 
1833     switch (m_pen
.GetCap()) 
1835         case wxCAP_PROJECTING
:  gs_cairo
->cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_SQUARE
); break; 
1836         case wxCAP_BUTT
:        gs_cairo
->cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_BUTT
); break; 
1838         default:                gs_cairo
->cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_ROUND
); break; 
1841     switch (m_pen
.GetJoin()) 
1843         case wxJOIN_BEVEL
:  gs_cairo
->cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_BEVEL
); break; 
1844         case wxJOIN_MITER
:  gs_cairo
->cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_MITER
); break; 
1846         default:            gs_cairo
->cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_ROUND
); break; 
1849     unsigned char red 
= m_pen
.GetColour().Red(); 
1850     unsigned char blue 
= m_pen
.GetColour().Blue(); 
1851     unsigned char green 
= m_pen
.GetColour().Green(); 
1852     unsigned char alpha 
= m_pen
.GetColour().Alpha(); 
1854     if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1856         double redPS 
= (double)(red
) / 255.0; 
1857         double bluePS 
= (double)(blue
) / 255.0; 
1858         double greenPS 
= (double)(green
) / 255.0; 
1859         double alphaPS 
= (double)(alpha
) / 255.0; 
1861         gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1864         m_currentBlue 
= blue
; 
1865         m_currentGreen 
= green
; 
1866         m_currentAlpha 
= alpha
; 
1870 void wxGtkPrintDC::SetBrush( const wxBrush
& brush 
) 
1872     if (!brush
.Ok()) return; 
1876     if (m_brush
.GetStyle() == wxTRANSPARENT
) 
1878         gs_cairo
->cairo_set_source_rgba( m_cairo
, 0, 0, 0, 0 ); 
1887     unsigned char red 
= m_brush
.GetColour().Red(); 
1888     unsigned char blue 
= m_brush
.GetColour().Blue(); 
1889     unsigned char green 
= m_brush
.GetColour().Green(); 
1890     unsigned char alpha 
= m_brush
.GetColour().Alpha(); 
1892     double redPS 
= (double)(red
) / 255.0; 
1893     double bluePS 
= (double)(blue
) / 255.0; 
1894     double greenPS 
= (double)(green
) / 255.0; 
1895     double alphaPS 
= (double)(alpha
) / 255.0; 
1897     if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1899         gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1902         m_currentBlue 
= blue
; 
1903         m_currentGreen 
= green
; 
1904         m_currentAlpha 
= alpha
; 
1907     if (m_brush
.IsHatch()) 
1910         cairo_surface_t 
*surface
; 
1911         surface 
= gs_cairo
->cairo_surface_create_similar(gs_cairo
->cairo_get_target(m_cairo
),CAIRO_CONTENT_COLOR_ALPHA
,10,10); 
1912         cr 
= gs_cairo
->cairo_create(surface
); 
1913         gs_cairo
->cairo_set_line_cap(cr
, CAIRO_LINE_CAP_SQUARE
); 
1914         gs_cairo
->cairo_set_line_width(cr
, 1); 
1915         gs_cairo
->cairo_set_line_join(cr
,CAIRO_LINE_JOIN_MITER
); 
1917         switch (m_brush
.GetStyle()) 
1920                 gs_cairo
->cairo_move_to(cr
, 5, 0); 
1921                 gs_cairo
->cairo_line_to(cr
, 5, 10); 
1922                 gs_cairo
->cairo_move_to(cr
, 0, 5); 
1923                 gs_cairo
->cairo_line_to(cr
, 10, 5); 
1925             case wxBDIAGONAL_HATCH
: 
1926                 gs_cairo
->cairo_move_to(cr
, 0, 10); 
1927                 gs_cairo
->cairo_line_to(cr
, 10, 0); 
1929             case wxFDIAGONAL_HATCH
: 
1930                 gs_cairo
->cairo_move_to(cr
, 0, 0); 
1931                 gs_cairo
->cairo_line_to(cr
, 10, 10); 
1933             case wxCROSSDIAG_HATCH
: 
1934                 gs_cairo
->cairo_move_to(cr
, 0, 0); 
1935                 gs_cairo
->cairo_line_to(cr
, 10, 10); 
1936                 gs_cairo
->cairo_move_to(cr
, 10, 0); 
1937                 gs_cairo
->cairo_line_to(cr
, 0, 10); 
1939             case wxHORIZONTAL_HATCH
: 
1940                 gs_cairo
->cairo_move_to(cr
, 0, 5); 
1941                 gs_cairo
->cairo_line_to(cr
, 10, 5); 
1943             case wxVERTICAL_HATCH
: 
1944                 gs_cairo
->cairo_move_to(cr
, 5, 0); 
1945                 gs_cairo
->cairo_line_to(cr
, 5, 10); 
1948                 wxFAIL_MSG(_("Couldn't get hatch style from wxBrush.")); 
1951         gs_cairo
->cairo_set_source_rgba(cr
, redPS
, greenPS
, bluePS
, alphaPS
); 
1952         gs_cairo
->cairo_stroke (cr
); 
1954         gs_cairo
->cairo_destroy(cr
); 
1955         cairo_pattern_t 
* pattern 
= gs_cairo
->cairo_pattern_create_for_surface (surface
); 
1956         gs_cairo
->cairo_surface_destroy(surface
); 
1957         gs_cairo
->cairo_pattern_set_extend (pattern
, CAIRO_EXTEND_REPEAT
); 
1958         gs_cairo
->cairo_set_source(m_cairo
, pattern
); 
1959         gs_cairo
->cairo_pattern_destroy(pattern
); 
1963 void wxGtkPrintDC::SetLogicalFunction( int function 
) 
1965     if (function 
== wxCLEAR
) 
1966         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_CLEAR
); 
1967     else if (function 
== wxOR
) 
1968         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_OUT
); 
1969     else if (function 
== wxNO_OP
) 
1970         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_DEST
); 
1971     else if (function 
== wxAND
) 
1972         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_ADD
); 
1973     else if (function 
== wxSET
) 
1974         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_SATURATE
); 
1975     else if (function 
== wxXOR
) 
1976         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_XOR
); 
1977     else // wxCOPY or anything else. 
1978         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_SOURCE
); 
1981 void wxGtkPrintDC::SetBackground( const wxBrush
& brush 
) 
1983     m_backgroundBrush 
= brush
; 
1984     gs_cairo
->cairo_save(m_cairo
); 
1985     gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_DEST_OVER
); 
1987     SetBrush(m_backgroundBrush
); 
1988     gs_cairo
->cairo_paint(m_cairo
); 
1989     gs_cairo
->cairo_restore(m_cairo
); 
1992 void wxGtkPrintDC::SetBackgroundMode(int mode
) 
1994     if (mode 
== wxSOLID
) m_backgroundMode 
= wxSOLID
; 
1995     else m_backgroundMode 
= wxTRANSPARENT
; 
1998 void wxGtkPrintDC::DoSetClippingRegion(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
2000     gs_cairo
->cairo_rectangle ( m_cairo
, XLOG2DEVREL(x
), YLOG2DEVREL(y
), XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
2001     gs_cairo
->cairo_clip(m_cairo
); 
2004 void wxGtkPrintDC::DestroyClippingRegion() 
2006     gs_cairo
->cairo_reset_clip(m_cairo
); 
2009 bool wxGtkPrintDC::StartDoc(const wxString
& message
) 
2014 void wxGtkPrintDC::EndDoc() 
2019 void wxGtkPrintDC::StartPage() 
2024 void wxGtkPrintDC::EndPage() 
2029 wxCoord 
wxGtkPrintDC::GetCharHeight() const 
2031     pango_layout_set_text( m_layout
, "H", 1 ); 
2034     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2036     return wxRound( h 
* m_PS2DEV 
); 
2039 wxCoord 
wxGtkPrintDC::GetCharWidth() const 
2041     pango_layout_set_text( m_layout
, "H", 1 ); 
2044     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2046     return wxRound( w 
* m_PS2DEV 
); 
2049 void wxGtkPrintDC::DoGetTextExtent(const wxString
& string
, wxCoord 
*width
, wxCoord 
*height
, 
2051                      wxCoord 
*externalLeading
, 
2052                      const wxFont 
*theFont 
) const 
2060     if ( externalLeading 
) 
2061         *externalLeading 
= 0; 
2068     // Set layout's text 
2069     // FIXME-UTF8: wouldn't be needed if utf8_str() always returned a buffer 
2070 #if wxUSE_UNICODE_UTF8 
2071     const char *dataUTF8 
= string
.utf8_str(); 
2073     const wxCharBuffer dataUTF8 
= string
.utf8_str(); 
2076     PangoFontDescription 
*desc 
= m_fontdesc
; 
2077     if (theFont
) desc 
= theFont
->GetNativeFontInfo()->description
; 
2079     gint oldSize 
= pango_font_description_get_size( desc 
); 
2080     double size 
= oldSize
; 
2081     size 
= size 
* m_scaleY
; 
2082     pango_font_description_set_size( desc
, (gint
)size 
); 
2084     // apply scaled font 
2085     pango_layout_set_font_description( m_layout
, desc 
); 
2087     pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) ); 
2090     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2093         *width 
= wxRound( (double)w 
/ m_scaleX 
* m_PS2DEV 
); 
2095         *height 
= wxRound( (double)h 
/ m_scaleY 
* m_PS2DEV 
); 
2099         PangoLayoutIter 
*iter 
= pango_layout_get_iter(m_layout
); 
2100         int baseline 
= pango_layout_iter_get_baseline(iter
); 
2101         pango_layout_iter_free(iter
); 
2102         *descent 
= wxRound( (h 
- PANGO_PIXELS(baseline
)) * m_PS2DEV 
); 
2105     // Reset unscaled size. 
2106     pango_font_description_set_size( desc
, oldSize 
); 
2108     // Reset unscaled font. 
2109     pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
2112 void wxGtkPrintDC::DoGetSize(int* width
, int* height
) const 
2114     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
2117         *width 
= wxRound( gtk_page_setup_get_paper_width( setup
, GTK_UNIT_POINTS 
) * m_PS2DEV 
); 
2119         *height 
= wxRound( gtk_page_setup_get_paper_height( setup
, GTK_UNIT_POINTS 
) * m_PS2DEV 
); 
2122 void wxGtkPrintDC::DoGetSizeMM(int *width
, int *height
) const 
2124     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
2127         *width 
= wxRound( gtk_page_setup_get_paper_width( setup
, GTK_UNIT_MM 
) ); 
2129         *height 
= wxRound( gtk_page_setup_get_paper_height( setup
, GTK_UNIT_MM 
) ); 
2132 wxSize 
wxGtkPrintDC::GetPPI() const 
2134     return wxSize( (int)m_resolution
, (int)m_resolution 
); 
2137 void wxGtkPrintDC::SetPrintData(const wxPrintData
& data
) 
2142 void wxGtkPrintDC::SetResolution(int ppi
) 
2144     // We can't change ppi of the GtkPrintContext. 
2145     // TODO: should we really support this? 
2148 int wxGtkPrintDC::GetResolution() 
2150     return m_resolution
; 
2153 // ---------------------------------------------------------------------------- 
2155 // ---------------------------------------------------------------------------- 
2157 IMPLEMENT_CLASS(wxGtkPrintPreview
, wxPrintPreviewBase
) 
2159 void wxGtkPrintPreview::Init(wxPrintout 
* WXUNUSED(printout
), 
2160                                     wxPrintout 
* WXUNUSED(printoutForPrinting
)) 
2165 wxGtkPrintPreview::wxGtkPrintPreview(wxPrintout 
*printout
, 
2166                                                    wxPrintout 
*printoutForPrinting
, 
2167                                                    wxPrintDialogData 
*data
) 
2168                         : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
2170     Init(printout
, printoutForPrinting
); 
2173 wxGtkPrintPreview::wxGtkPrintPreview(wxPrintout 
*printout
, 
2174                                                    wxPrintout 
*printoutForPrinting
, 
2176                         : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
2178     Init(printout
, printoutForPrinting
); 
2181 wxGtkPrintPreview::~wxGtkPrintPreview() 
2185 bool wxGtkPrintPreview::Print(bool interactive
) 
2187     if (!m_printPrintout
) 
2190     wxPrinter 
printer(& m_printDialogData
); 
2191     return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
); 
2194 void wxGtkPrintPreview::DetermineScaling() 
2196     wxPaperSize paperType 
= m_printDialogData
.GetPrintData().GetPaperId(); 
2198     wxPrintPaperType 
*paper 
= wxThePrintPaperDatabase
->FindPaperType(paperType
); 
2200         paper 
= wxThePrintPaperDatabase
->FindPaperType(wxPAPER_A4
); 
2204         wxSize ScreenPixels 
= wxGetDisplaySize(); 
2205         wxSize ScreenMM 
= wxGetDisplaySizeMM(); 
2207         m_previewPrintout
->SetPPIScreen( (int) ((ScreenPixels
.GetWidth() * 25.4) / ScreenMM
.GetWidth()), 
2208                                          (int) ((ScreenPixels
.GetHeight() * 25.4) / ScreenMM
.GetHeight()) ); 
2210         // TODO !!!!!!!!!!!!!!!       
2211         int resolution 
= 600; 
2212         m_previewPrintout
->SetPPIPrinter( resolution
, resolution 
); 
2214         // Get width and height in points (1/72th of an inch) 
2215         wxSize 
sizeDevUnits(paper
->GetSizeDeviceUnits()); 
2217         sizeDevUnits
.x 
= wxRound((double)sizeDevUnits
.x 
* (double)resolution 
/ 72.0); 
2218         sizeDevUnits
.y 
= wxRound((double)sizeDevUnits
.y 
* (double)resolution 
/ 72.0); 
2219         wxSize 
sizeTenthsMM(paper
->GetSize()); 
2220         wxSize 
sizeMM(sizeTenthsMM
.x 
/ 10, sizeTenthsMM
.y 
/ 10); 
2222         // If in landscape mode, we need to swap the width and height. 
2223         if ( m_printDialogData
.GetPrintData().GetOrientation() == wxLANDSCAPE 
) 
2225             m_pageWidth 
= sizeDevUnits
.y
; 
2226             m_pageHeight 
= sizeDevUnits
.x
; 
2227             m_previewPrintout
->SetPageSizeMM(sizeMM
.y
, sizeMM
.x
); 
2231             m_pageWidth 
= sizeDevUnits
.x
; 
2232             m_pageHeight 
= sizeDevUnits
.y
; 
2233             m_previewPrintout
->SetPageSizeMM(sizeMM
.x
, sizeMM
.y
); 
2235         m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
); 
2236         m_previewPrintout
->SetPaperRectPixels(wxRect(0, 0, m_pageWidth
, m_pageHeight
)); 
2238         // At 100%, the page should look about page-size on the screen. 
2239         m_previewScaleX 
= 0.8 * 72.0 / (double)resolution
; 
2240         m_previewScaleY 
= m_previewScaleX
;