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 
); 
  85 void wxGtkPrintModule::OnExit() 
  90 IMPLEMENT_DYNAMIC_CLASS(wxGtkPrintModule
, wxModule
) 
  92 //---------------------------------------------------------------------------- 
  94 //---------------------------------------------------------------------------- 
  96 wxPrinterBase
* wxGtkPrintFactory::CreatePrinter( wxPrintDialogData 
*data 
) 
  98     return new wxGtkPrinter( data 
); 
 101 wxPrintPreviewBase 
*wxGtkPrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 102                                                     wxPrintout 
*printout
, 
 103                                                     wxPrintDialogData 
*data 
) 
 105     return new wxGtkPrintPreview( preview
, printout
, data 
); 
 108 wxPrintPreviewBase 
*wxGtkPrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 109                                                     wxPrintout 
*printout
, 
 112     return new wxGtkPrintPreview( preview
, printout
, data 
); 
 115 wxPrintDialogBase 
*wxGtkPrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 116                                                   wxPrintDialogData 
*data 
) 
 118     return new wxGtkPrintDialog( parent
, data 
); 
 121 wxPrintDialogBase 
*wxGtkPrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 124     return new wxGtkPrintDialog( parent
, data 
); 
 127 wxPageSetupDialogBase 
*wxGtkPrintFactory::CreatePageSetupDialog( wxWindow 
*parent
, 
 128                                                           wxPageSetupDialogData 
* data 
) 
 130     return new wxGtkPageSetupDialog( parent
, data 
); 
 133 bool wxGtkPrintFactory::HasPrintSetupDialog() 
 138 wxDialog 
*wxGtkPrintFactory::CreatePrintSetupDialog( wxWindow 
*parent
, wxPrintData 
*data 
) 
 143 wxDC
* wxGtkPrintFactory::CreatePrinterDC( const wxPrintData
& data 
) 
 145     return new wxGtkPrintDC(data
); 
 148 bool wxGtkPrintFactory::HasOwnPrintToFile() 
 153 bool wxGtkPrintFactory::HasPrinterLine() 
 158 wxString 
wxGtkPrintFactory::CreatePrinterLine() 
 161     return wxEmptyString
; 
 164 bool wxGtkPrintFactory::HasStatusLine() 
 170 wxString 
wxGtkPrintFactory::CreateStatusLine() 
 173     return wxEmptyString
; 
 176 wxPrintNativeDataBase 
*wxGtkPrintFactory::CreatePrintNativeData() 
 178     return new wxGtkPrintNativeData
; 
 181 //---------------------------------------------------------------------------- 
 182 // Callback functions for Gtk Printings. 
 183 //---------------------------------------------------------------------------- 
 185 // We use it to pass useful objets to gtk printing callback functions. 
 188    wxGtkPrinter 
* printer
; 
 189    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 
*operation
, GtkPrintContext 
*context
, gpointer user_data
) 
 211         wxPrintout 
*printout 
= (wxPrintout 
*) user_data
; 
 213         printout
->OnEndPrinting(); 
 216     static gboolean 
gtk_preview_print_callback (GtkPrintOperation 
*operation
, GtkPrintOperationPreview 
*preview
, GtkPrintContext 
*context
, GtkWindow 
*parent
, gpointer user_data
) 
 218         wxPrintout 
*printout 
= (wxPrintout 
*) user_data
; 
 220         printout
->SetIsPreview(true); 
 222         /* We create a cairo context with 72dpi resolution. This resolution is only used for positionning. */ 
 223         cairo_t 
*cairo 
= gdk_cairo_create(GTK_WIDGET(parent
)->window
); 
 224         gtk_print_context_set_cairo_context(context
, cairo
, 72, 72); 
 230 //---------------------------------------------------------------------------- 
 231 // wxGtkPrintNativeData 
 232 //---------------------------------------------------------------------------- 
 234 IMPLEMENT_CLASS(wxGtkPrintNativeData
, wxPrintNativeDataBase
) 
 236 wxGtkPrintNativeData::wxGtkPrintNativeData() 
 238     m_config 
= gtk_print_settings_new(); 
 241 wxGtkPrintNativeData::~wxGtkPrintNativeData() 
 243     g_object_unref (m_config
); 
 246 // Convert datas stored in m_config to a wxPrintData. 
 247 // Called by wxPrintData::ConvertFromNative(). 
 248 bool wxGtkPrintNativeData::TransferTo( wxPrintData 
&data 
) 
 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
); 
 263     data
.SetNoCopies(gtk_print_settings_get_n_copies(m_config
)); 
 265     data
.SetColour(gtk_print_settings_get_use_color(m_config
)); 
 267     switch (gtk_print_settings_get_duplex(m_config
)) 
 269         case GTK_PRINT_DUPLEX_SIMPLEX
:      data
.SetDuplex (wxDUPLEX_SIMPLEX
); 
 272         case GTK_PRINT_DUPLEX_HORIZONTAL
:   data
.SetDuplex (wxDUPLEX_HORIZONTAL
); 
 276         case GTK_PRINT_DUPLEX_VERTICAL
:      data
.SetDuplex (wxDUPLEX_VERTICAL
); 
 280     GtkPageOrientation orientation 
= gtk_print_settings_get_orientation (m_config
); 
 281     if (orientation 
== GTK_PAGE_ORIENTATION_PORTRAIT
) 
 283         data
.SetOrientation(wxPORTRAIT
); 
 284         data
.SetOrientationReversed(false); 
 286     else if (orientation 
== GTK_PAGE_ORIENTATION_LANDSCAPE
) 
 288         data
.SetOrientation(wxLANDSCAPE
); 
 289         data
.SetOrientationReversed(false); 
 291     else if (orientation 
== GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
) 
 293         data
.SetOrientation(wxPORTRAIT
); 
 294         data
.SetOrientationReversed(true); 
 296     else if (orientation 
== GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
) 
 298         data
.SetOrientation(wxLANDSCAPE
); 
 299         data
.SetOrientationReversed(true); 
 302     data
.SetCollate(gtk_print_settings_get_collate (m_config
)); 
 304     // Paper formats : these are the most common paper formats. 
 305     GtkPaperSize 
*paper_size 
= gtk_print_settings_get_paper_size (m_config
); 
 307         data
.SetPaperId(wxPAPER_NONE
); 
 308     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_A3
))) 
 309         data
.SetPaperId(wxPAPER_A3
); 
 310     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_A4
))) 
 311         data
.SetPaperId(wxPAPER_A4
); 
 312     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_A5
))) 
 313         data
.SetPaperId(wxPAPER_A5
); 
 314     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_B5
))) 
 315         data
.SetPaperId(wxPAPER_B5
); 
 316     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_LETTER
))) 
 317         data
.SetPaperId(wxPAPER_LETTER
); 
 318     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_LEGAL
))) 
 319         data
.SetPaperId(wxPAPER_LEGAL
); 
 320     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE
))) 
 321         data
.SetPaperId(wxPAPER_EXECUTIVE
); 
 322     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"na_number-10"))) 
 323         data
.SetPaperId(wxPAPER_ENV_10
); 
 324     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c5"))) 
 325         data
.SetPaperId(wxPAPER_ENV_C5
); 
 326     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c6"))) 
 327         data
.SetPaperId(wxPAPER_ENV_C6
); 
 328     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"jis-b5"))) 
 329         data
.SetPaperId(wxPAPER_B5_TRANSVERSE
); 
 330     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b5"))) 
 331         data
.SetPaperId(wxPAPER_ENV_B5
); 
 332     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"na_monarch"))) 
 333         data
.SetPaperId(wxPAPER_ENV_MONARCH
); 
 334     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-c"))) 
 335         data
.SetPaperId( wxPAPER_CSHEET
); 
 336     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-d"))) 
 337         data
.SetPaperId( wxPAPER_DSHEET
); 
 338     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-e"))) 
 339         data
.SetPaperId( wxPAPER_ESHEET
); 
 340     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"letter"))) 
 341         data
.SetPaperId( wxPAPER_LETTERSMALL
); 
 342     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"engineering-b"))) 
 343         data
.SetPaperId( wxPAPER_TABLOID
); 
 344     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"ledger"))) 
 345         data
.SetPaperId( wxPAPER_LEDGER
); 
 346     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"statement"))) 
 347         data
.SetPaperId( wxPAPER_STATEMENT
); 
 348     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( GTK_PAPER_NAME_A4 
))) 
 349         data
.SetPaperId( wxPAPER_A4SMALL
); 
 350     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b4"))) 
 351         data
.SetPaperId( wxPAPER_B4
); 
 352     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"folio"))) 
 353         data
.SetPaperId( wxPAPER_FOLIO
); 
 354     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"quarto"))) 
 355         data
.SetPaperId( wxPAPER_QUARTO
); 
 356     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"10x14"))) 
 357         data
.SetPaperId( wxPAPER_10X14
); 
 358     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"ledger"))) 
 359         data
.SetPaperId( wxPAPER_11X17
); 
 360     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"letter"))) 
 361         data
.SetPaperId( wxPAPER_NOTE
); 
 362     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"na-number-9-envelope"))) 
 363         data
.SetPaperId( wxPAPER_ENV_9
); 
 364     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"number-11"))) 
 365         data
.SetPaperId( wxPAPER_ENV_11
); 
 366     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"number-12"))) 
 367         data
.SetPaperId( wxPAPER_ENV_12
); 
 368     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"number-14"))) 
 369         data
.SetPaperId( wxPAPER_ENV_14
); 
 370     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-designated"))) 
 371         data
.SetPaperId( wxPAPER_ENV_DL
); 
 372     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c3"))) 
 373         data
.SetPaperId( wxPAPER_ENV_C3
); 
 374     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-c4"))) 
 375         data
.SetPaperId( wxPAPER_ENV_C4
); 
 376     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"c6/c5"))) 
 377         data
.SetPaperId( wxPAPER_ENV_C65
); 
 378     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b4"))) 
 379         data
.SetPaperId( wxPAPER_ENV_B4
); 
 380     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"iso-b6"))) 
 381             data
.SetPaperId( wxPAPER_ENV_B6
); 
 382     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"Italian"))) 
 383         data
.SetPaperId( wxPAPER_ENV_ITALY
); 
 384     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"personal"))) 
 385         data
.SetPaperId( wxPAPER_ENV_PERSONAL
); 
 386     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"fanfold-us"))) 
 387         data
.SetPaperId( wxPAPER_FANFOLD_US
); 
 388     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"fanfold-European"))) 
 389         data
.SetPaperId( wxPAPER_FANFOLD_STD_GERMAN
); 
 390     else if (gtk_paper_size_is_equal(paper_size
,gtk_paper_size_new ( (const gchar
*)"foolscap"))) 
 391         data
.SetPaperId( wxPAPER_FANFOLD_LGL_GERMAN
); 
 393         data
.SetPaperId(wxPAPER_NONE
); 
 397 // Put datas given by the wxPrintData into m_config. 
 398 // Called by wxPrintData::ConvertToNative(). 
 399 bool wxGtkPrintNativeData::TransferFrom( const wxPrintData 
&data 
) 
 404     wxPrintQuality quality 
= data
.GetQuality(); 
 405     if (quality 
== wxPRINT_QUALITY_HIGH
) 
 406         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_HIGH
); 
 407     else if (quality 
== wxPRINT_QUALITY_MEDIUM
) 
 408         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_NORMAL
); 
 409     else if (quality 
== wxPRINT_QUALITY_LOW
) 
 410         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_LOW
); 
 411     else if (quality 
== wxPRINT_QUALITY_DRAFT
) 
 412         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_DRAFT
); 
 413     else if (quality 
> 1) 
 414         gtk_print_settings_set_resolution (m_config
, quality
); 
 416         gtk_print_settings_set_quality (m_config
, GTK_PRINT_QUALITY_NORMAL
); 
 418     gtk_print_settings_set_n_copies(m_config
, data
.GetNoCopies()); 
 420     gtk_print_settings_set_use_color(m_config
, data
.GetColour()); 
 422     switch (data
.GetDuplex()) 
 424         case wxDUPLEX_SIMPLEX
:      gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_SIMPLEX
); 
 427         case wxDUPLEX_HORIZONTAL
:   gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_HORIZONTAL
); 
 431         case wxDUPLEX_VERTICAL
:      gtk_print_settings_set_duplex (m_config
, GTK_PRINT_DUPLEX_VERTICAL
); 
 435     if (!data
.IsOrientationReversed()) 
 437         if (data
.GetOrientation() == wxLANDSCAPE
) 
 438             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_LANDSCAPE
); 
 440             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_PORTRAIT
); 
 443         if (data
.GetOrientation() == wxLANDSCAPE
) 
 444             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
); 
 446             gtk_print_settings_set_orientation (m_config
, GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
); 
 449     gtk_print_settings_set_collate (m_config
, data
.GetCollate()); 
 451     // Paper formats: these are the most common paper formats. 
 452     switch (data
.GetPaperId()) 
 454         case wxPAPER_A3
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A3
)); 
 456         case wxPAPER_A4
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A4
)); 
 458         case wxPAPER_A5
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A5
)); 
 460         case wxPAPER_B5_TRANSVERSE
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "jis-b5")); 
 462         case wxPAPER_B5
:        gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_B5
)); 
 464         case wxPAPER_LETTER
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_LETTER
)); 
 466         case wxPAPER_LEGAL
:     gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_LEGAL
)); 
 468         case wxPAPER_EXECUTIVE
: gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE
)); 
 470         case wxPAPER_ENV_10
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na_number-10")); 
 472         case wxPAPER_ENV_C5
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c5")); 
 474         case wxPAPER_ENV_C6
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c6")); 
 476         case wxPAPER_ENV_B5
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c5b5")); 
 478         case wxPAPER_ENV_MONARCH
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na_monarch")); 
 480         case wxPAPER_CSHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-c")); 
 482         case wxPAPER_DSHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-d")); 
 484         case wxPAPER_ESHEET
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-e")); 
 486         case wxPAPER_LETTERSMALL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "letter")); 
 488         case wxPAPER_TABLOID
:   gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "engineering-b")); 
 490         case wxPAPER_LEDGER
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "ledger")); 
 492         case wxPAPER_STATEMENT
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "statement")); 
 494         case wxPAPER_A4SMALL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new (GTK_PAPER_NAME_A4
)); 
 496         case wxPAPER_B4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b4")); 
 498         case wxPAPER_FOLIO
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "folio")); 
 500         case wxPAPER_QUARTO
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "quarto")); 
 502         case wxPAPER_10X14
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "10x14")); 
 504         case wxPAPER_11X17
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "ledger")); 
 506         case wxPAPER_NOTE
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "letter")); 
 508         case wxPAPER_ENV_9
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "na-number-9-envelope")); 
 510         case wxPAPER_ENV_11
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-11")); 
 512         case wxPAPER_ENV_12
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-12")); 
 514         case wxPAPER_ENV_14
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "number-14")); 
 516         case wxPAPER_ENV_DL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-designated")); 
 518         case wxPAPER_ENV_C3
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c3")); 
 520         case wxPAPER_ENV_C4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-c4")); 
 522         case wxPAPER_ENV_C65
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "c6/c5")); 
 524         case wxPAPER_ENV_B4
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b4")); 
 526         case wxPAPER_ENV_B6
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "iso-b6")); 
 528         case wxPAPER_ENV_ITALY
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "Italian")); 
 530         case wxPAPER_ENV_PERSONAL
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "personal")); 
 532         case wxPAPER_FANFOLD_US
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "fanfold-us")); 
 534         case wxPAPER_FANFOLD_STD_GERMAN
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "fanfold-European")); 
 536         case wxPAPER_FANFOLD_LGL_GERMAN
:    gtk_print_settings_set_paper_size(m_config
, gtk_paper_size_new ((const gchar
*) "foolscap")); 
 545 void wxGtkPrintNativeData::SetPrintConfig( GtkPrintSettings 
* config 
) 
 548         m_config 
= gtk_print_settings_copy(config
); 
 551 // Extract page setup from settings. 
 552 GtkPageSetup
* wxGtkPrintNativeData::GetPageSetupFromSettings(GtkPrintSettings
* settings
) 
 554     GtkPageSetup
* page_setup 
= gtk_page_setup_new(); 
 555         gtk_page_setup_set_orientation (page_setup
, gtk_print_settings_get_orientation (settings
)); 
 557         GtkPaperSize 
*paper_size 
= gtk_print_settings_get_paper_size (settings
); 
 558         if (paper_size 
!= NULL
) 
 559                 gtk_page_setup_set_paper_size_and_default_margins (page_setup
, paper_size
); 
 564 // Insert page setup into a given GtkPrintSettings. 
 565 void wxGtkPrintNativeData::SetPageSetupToSettings(GtkPrintSettings
* settings
, GtkPageSetup
* page_setup
) 
 567     gtk_print_settings_set_orientation ( settings
, gtk_page_setup_get_orientation (page_setup
)); 
 568         gtk_print_settings_set_paper_size ( settings
, gtk_page_setup_get_paper_size (page_setup
)); 
 571 //---------------------------------------------------------------------------- 
 573 //---------------------------------------------------------------------------- 
 575 IMPLEMENT_CLASS(wxGtkPrintDialog
, wxPrintDialogBase
) 
 577 wxGtkPrintDialog::wxGtkPrintDialog( wxWindow 
*parent
, wxPrintDialogData 
*data 
) 
 578                     : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"), 
 579                                wxPoint(0, 0), wxSize(600, 600), 
 580                                wxDEFAULT_DIALOG_STYLE 
| 
 584         m_printDialogData 
= *data
; 
 590 wxGtkPrintDialog::wxGtkPrintDialog( wxWindow 
*parent
, wxPrintData 
*data 
) 
 591                     : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"), 
 592                                wxPoint(0, 0), wxSize(600, 600), 
 593                                wxDEFAULT_DIALOG_STYLE 
| 
 597         m_printDialogData 
= *data
; 
 604 wxGtkPrintDialog::~wxGtkPrintDialog() 
 608 // This is called even if we actually don't want the dialog to appear. 
 609 int wxGtkPrintDialog::ShowModal() 
 611     GtkPrintOperationResult response
; 
 613     // We need to restore the settings given in the constructor. 
 614     wxPrintData data 
= m_printDialogData
.GetPrintData(); 
 615     wxGtkPrintNativeData 
*native 
= 
 616       (wxGtkPrintNativeData
*) data
.GetNativeData(); 
 617     data
.ConvertToNative(); 
 619     GtkPrintSettings 
* settings 
= native
->GetPrintConfig(); 
 621     // We have to restore pages to print here because they're stored in a wxPrintDialogData and ConvertToNative only works for wxPrintData. 
 622     int fromPage 
= m_printDialogData
.GetFromPage(); 
 623     int toPage 
= m_printDialogData
.GetToPage(); 
 624     if (m_printDialogData
.GetSelection()) 
 625         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_CURRENT
); 
 626     else if (m_printDialogData
.GetAllPages()) 
 627         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_ALL
); 
 629         gtk_print_settings_set_print_pages(settings
, GTK_PRINT_PAGES_RANGES
); 
 631         range 
= g_new (GtkPageRange
, 1); 
 632         range
[0].start 
= fromPage
-1; 
 633         range
[0].end 
= (toPage 
>= fromPage
) ? toPage
-1 : fromPage
-1; 
 634         gtk_print_settings_set_page_ranges (settings
, range
, 1); 
 637     // If the settings are OK, we restore it. 
 638     if (settings 
!= NULL
) 
 639         gtk_print_operation_set_print_settings (native
->GetPrintJob(), settings
); 
 640         gtk_print_operation_set_default_page_setup (native
->GetPrintJob(), native
->GetPageSetupFromSettings(settings
)); 
 642     // Show the dialog if needed. 
 643     GError
* gError 
= NULL
; 
 645         response 
= gtk_print_operation_run (native
->GetPrintJob(), GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
, GTK_WINDOW(gtk_widget_get_toplevel(m_parent
->m_widget
) ), &gError
); 
 647         response 
= gtk_print_operation_run (native
->GetPrintJob(), GTK_PRINT_OPERATION_ACTION_PRINT
, (GtkWindow 
*) m_parent
, &gError
); 
 649     // Does everything went well? 
 650     if (response 
== GTK_PRINT_OPERATION_RESULT_CANCEL
) 
 654     else if (response 
== GTK_PRINT_OPERATION_RESULT_ERROR
) 
 656         g_error_free (gError
); 
 657         wxLogError(_("Error while printing: ") + wxString::Format(_("%s"), gError
->message
)); 
 658         return wxID_NO
; // We use wxID_NO because there is no wxID_ERROR available 
 661     // Now get the settings and save it. 
 662     GtkPrintSettings
* newSettings 
= gtk_print_operation_get_print_settings (native
->GetPrintJob()); 
 663     native
->SetPrintConfig(newSettings
); 
 664     data
.ConvertFromNative(); 
 666     // Same problem as a few lines before. 
 667     switch (gtk_print_settings_get_print_pages(newSettings
)) 
 669         case GTK_PRINT_PAGES_CURRENT
: 
 670             m_printDialogData
.SetSelection( true ); 
 672         case GTK_PRINT_PAGES_RANGES
: 
 673             {// wxWidgets doesn't support multiple ranges, so we can only save the first one even if the user wants to print others. 
 674             // 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 
 675             // will hit "OK" button. However we can only save 1-3 in the print data. 
 678             range 
= gtk_print_settings_get_page_ranges (newSettings
, &num_ranges
); 
 681             m_printDialogData
.SetFromPage( range
[0].start 
); 
 682             m_printDialogData
.SetToPage( range
[0].end 
); 
 685                 m_printDialogData
.SetAllPages( true ); 
 686                 m_printDialogData
.SetFromPage( 0 ); 
 687                 m_printDialogData
.SetToPage( 9999 ); 
 690         case GTK_PRINT_PAGES_ALL
: 
 692             m_printDialogData
.SetAllPages( true ); 
 693             m_printDialogData
.SetFromPage( 0 ); 
 694             m_printDialogData
.SetToPage( 9999 ); 
 701 //---------------------------------------------------------------------------- 
 702 // wxGtkPageSetupDialog 
 703 //---------------------------------------------------------------------------- 
 705 IMPLEMENT_CLASS(wxGtkPageSetupDialog
, wxPageSetupDialogBase
) 
 707 wxGtkPageSetupDialog::wxGtkPageSetupDialog( wxWindow 
*parent
, 
 708                             wxPageSetupDialogData
* data 
) 
 711         m_pageDialogData 
= *data
; 
 716 wxGtkPageSetupDialog::~wxGtkPageSetupDialog() 
 720 int wxGtkPageSetupDialog::ShowModal() 
 723     m_pageDialogData
.GetPrintData().ConvertToNative(); 
 724     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) m_pageDialogData
.GetPrintData().GetNativeData(); 
 725     GtkPrintSettings
* nativeData 
= native
->GetPrintConfig(); 
 727     // We only need the pagesetup data which are part of the settings. 
 728     GtkPageSetup
* oldPageSetup 
= native
->GetPageSetupFromSettings(nativeData
); 
 730     // If the user used a custom paper format the last time he printed, we have to restore it too. 
 731     if (m_pageDialogData
.GetPrintData().GetPaperId() == wxPAPER_NONE
) 
 733         wxSize customPaperSize 
= m_pageDialogData
.GetPaperSize(); 
 734         if (customPaperSize
.GetWidth() > 0 && customPaperSize
.GetHeight() > 0) 
 736             wxString title 
= _("Custom size"); 
 737             GtkPaperSize
* customSize 
= gtk_paper_size_new_custom ("custom", title
.mb_str(), (gdouble
) customPaperSize
.GetWidth(), (gdouble
) customPaperSize
.GetHeight(), GTK_UNIT_MM
); 
 738             gtk_page_setup_set_paper_size_and_default_margins (oldPageSetup
, customSize
); 
 739             g_object_unref(customSize
); 
 743     // Now show the dialog. 
 744     GtkPageSetup
* newPageSetup 
= gtk_print_run_page_setup_dialog (GTK_WINDOW(m_parent
->m_widget
), 
 749     if (newPageSetup 
!= oldPageSetup
) 
 751         native
->SetPageSetupToSettings(nativeData
, newPageSetup
); 
 752         m_pageDialogData
.GetPrintData().ConvertFromNative(); 
 754         // Store custom paper format if any. 
 755         if (m_pageDialogData
.GetPrintData().GetPaperId() == wxPAPER_NONE
) 
 757             gdouble ml
,mr
,mt
,mb
,pw
,ph
; 
 758             ml 
= gtk_page_setup_get_left_margin (newPageSetup
, GTK_UNIT_MM
); 
 759             mr 
= gtk_page_setup_get_right_margin (newPageSetup
, GTK_UNIT_MM
); 
 760             mt 
= gtk_page_setup_get_top_margin (newPageSetup
, GTK_UNIT_MM
); 
 761             mb 
= gtk_page_setup_get_bottom_margin (newPageSetup
, GTK_UNIT_MM
); 
 763             pw 
= gtk_page_setup_get_paper_width (newPageSetup
, GTK_UNIT_MM
); 
 764             ph 
= gtk_page_setup_get_paper_height (newPageSetup
, GTK_UNIT_MM
); 
 766             m_pageDialogData
.SetMarginTopLeft( wxPoint( (int)(ml
+0.5), (int)(mt
+0.5)) ); 
 767             m_pageDialogData
.SetMarginBottomRight( wxPoint( (int)(mr
+0.5), (int)(mb
+0.5)) ); 
 769             m_pageDialogData
.SetPaperSize( wxSize( (int)(pw
+0.5), (int)(ph
+0.5) ) ); 
 782 //---------------------------------------------------------------------------- 
 784 //---------------------------------------------------------------------------- 
 786 IMPLEMENT_CLASS(wxGtkPrinter
, wxPrinterBase
) 
 788 wxGtkPrinter::wxGtkPrinter( wxPrintDialogData 
*data 
) : 
 789     wxPrinterBase( data 
) 
 794         m_printDialogData 
= *data
; 
 797 wxGtkPrinter::~wxGtkPrinter() 
 801 bool wxGtkPrinter::Print(wxWindow 
*parent
, wxPrintout 
*printout
, bool prompt 
) 
 805         sm_lastError 
= wxPRINTER_ERROR
; 
 809     // Let's correct the PageInfo just in case the app gives wrong values. 
 810     int fromPage
, toPage
; 
 811     int minPage
, maxPage
; 
 812     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 813     m_printDialogData
.SetAllPages(true); 
 815     if (minPage 
< 1) minPage 
= 1; 
 816     if (maxPage 
< 1) maxPage 
= 9999; 
 817     if (maxPage 
< minPage
) maxPage 
= minPage
; 
 819     m_printDialogData
.SetMinPage(minPage
); 
 820     m_printDialogData
.SetMaxPage(maxPage
); 
 823         if (fromPage 
< minPage
) fromPage 
= minPage
; 
 824         else if (fromPage 
> maxPage
) fromPage 
= maxPage
; 
 825         m_printDialogData
.SetFromPage(fromPage
); 
 829         m_printDialogData
.SetToPage(toPage
); 
 830         if (toPage 
> maxPage
) toPage 
= maxPage
; 
 831         else if (toPage 
< minPage
) toPage 
= minPage
; 
 834     if (((minPage 
!= fromPage
) && fromPage 
!= 0) || ((maxPage 
!= toPage
) && toPage 
!= 0)) m_printDialogData
.SetAllPages(false); 
 837     wxPrintData printdata 
= GetPrintDialogData().GetPrintData(); 
 838     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) printdata
.GetNativeData(); 
 840     GtkPrintOperation 
*printOp 
= gtk_print_operation_new (); 
 842     native
->SetPrintJob( printOp 
); 
 844     printout
->SetIsPreview(false); 
 846     wxPrinterToGtkData dataToSend
; 
 847     dataToSend
.printer 
= this; 
 848     dataToSend
.printout 
= printout
; 
 850     // These Gtk signals are catched here. 
 851     g_signal_connect (printOp
, "begin-print", G_CALLBACK (gtk_begin_print_callback
), &dataToSend
); 
 852     g_signal_connect (printOp
, "draw-page", G_CALLBACK (gtk_draw_page_print_callback
), &dataToSend
); 
 853     g_signal_connect (printOp
, "end-print", G_CALLBACK (gtk_end_print_callback
), printout
); 
 854     g_signal_connect (printOp
, "preview", G_CALLBACK (gtk_preview_print_callback
), printout
); 
 858         m_showDialog 
= false; 
 860     // PrintDialog returns a wxDC but we created it before so we don't need it anymore: we just delete it. 
 861     wxDC
* uselessdc 
= PrintDialog( parent 
); 
 864     g_object_unref (printOp
); 
 866     return (sm_lastError 
== wxPRINTER_NO_ERROR
); 
 869 void wxGtkPrinter::BeginPrint(wxPrintout 
*printout
, GtkPrintOperation 
*operation
, GtkPrintContext 
*context
) 
 871     wxPrintData printdata 
= GetPrintDialogData().GetPrintData(); 
 872     wxGtkPrintNativeData 
*native 
= (wxGtkPrintNativeData
*) printdata
.GetNativeData(); 
 874     SetPrintContext(context
); 
 875     native
->SetPrintContext( context 
); 
 877     wxGtkPrintDC 
*printDC 
= new wxGtkPrintDC( printdata 
); 
 882         if (sm_lastError 
!= wxPRINTER_CANCELLED
) 
 884             sm_lastError 
= wxPRINTER_ERROR
; 
 885             wxFAIL_MSG(_("The wxGtkPrintDC cannot be used.")); 
 889     wxSize ScreenPixels 
= wxGetDisplaySize(); 
 890     wxSize ScreenMM 
= wxGetDisplaySizeMM(); 
 892     printout
->SetPPIScreen( (int) ((ScreenPixels
.GetWidth() * 25.4) / ScreenMM
.GetWidth()), 
 893                             (int) ((ScreenPixels
.GetHeight() * 25.4) / ScreenMM
.GetHeight()) ); 
 894     printout
->SetPPIPrinter( printDC
->GetResolution(), 
 895                              printDC
->GetResolution() ); 
 897     printout
->SetDC(m_dc
); 
 900     m_dc
->GetSize(&w
, &h
); 
 901     printout
->SetPageSizePixels((int)w
, (int)h
); 
 902     printout
->SetPaperRectPixels(wxRect(0, 0, w
, h
)); 
 904     m_dc
->GetSizeMM(&mw
, &mh
); 
 905     printout
->SetPageSizeMM((int)mw
, (int)mh
); 
 906     printout
->OnPreparePrinting(); 
 908     // Get some parameters from the printout, if defined. 
 909     int fromPage
, toPage
; 
 910     int minPage
, maxPage
; 
 911     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 915         sm_lastError 
= wxPRINTER_ERROR
; 
 916         wxFAIL_MSG(_("wxPrintout::GetPageInfo gives a null maxPage.")); 
 920     printout
->OnBeginPrinting(); 
 924     // If we're not previewing we need to calculate the number of pages to print. 
 925     // If we're previewing, Gtk Print will render every pages without wondering about the page ranges the user may 
 926     // have defined in the dialog. So the number of pages is the maximum available. 
 927     if (!printout
->IsPreview()) 
 929         GtkPrintSettings 
* settings 
= gtk_print_operation_get_print_settings (operation
); 
 930         switch (gtk_print_settings_get_print_pages(settings
)) 
 932             case GTK_PRINT_PAGES_CURRENT
: 
 935             case GTK_PRINT_PAGES_RANGES
: 
 936                 {gint num_ranges 
= 0; 
 939                 range 
= gtk_print_settings_get_page_ranges (settings
, &num_ranges
); 
 940                 for (i
=0; i
<num_ranges
; i
++) 
 942                     if (range
[i
].end 
< range
[i
].start
) range
[i
].end 
= range
[i
].start
; 
 943                     if (range
[i
].start 
< minPage
-1) range
[i
].start 
= minPage
-1; 
 944                     if (range
[i
].end 
> maxPage
-1) range
[i
].end 
= maxPage
-1; 
 945                     if (range
[i
].start 
> maxPage
-1) range
[i
].start 
= maxPage
-1; 
 946                     numPages 
+= range
[i
].end 
- range
[i
].start 
+ 1; 
 948                 gtk_print_settings_set_page_ranges (settings
, range
, 1); 
 950             case GTK_PRINT_PAGES_ALL
: 
 952                 numPages 
= maxPage 
- minPage 
+ 1; 
 956     else numPages 
= maxPage 
- minPage 
+ 1; 
 958     gtk_print_operation_set_n_pages(operation
, numPages
); 
 961 void wxGtkPrinter::DrawPage(wxPrintout 
*printout
, GtkPrintOperation 
*operation
, GtkPrintContext 
*context
, int page_nr
) 
 963     int fromPage
, toPage
, minPage
, maxPage
, startPage
, endPage
; 
 964     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 966     int numPageToDraw 
= page_nr 
+ minPage
; 
 967     if (numPageToDraw 
< minPage
) numPageToDraw 
= minPage
; 
 968     if (numPageToDraw 
> maxPage
) numPageToDraw 
= maxPage
; 
 970     GtkPrintSettings 
* settings 
= gtk_print_operation_get_print_settings (operation
); 
 971     switch (gtk_print_settings_get_print_pages(settings
)) 
 973         case GTK_PRINT_PAGES_CURRENT
: 
 974             g_object_get_property((GObject
*) operation
, (const gchar 
*) "current-page", (GValue
*) &startPage
); 
 975             g_object_get_property((GObject
*) operation
, (const gchar 
*) "current-page", (GValue
*) &endPage
); 
 977         case GTK_PRINT_PAGES_RANGES
: 
 978             {gint num_ranges 
= 0; 
 980             range 
= gtk_print_settings_get_page_ranges (settings
, &num_ranges
); 
 981             // We don't need to verify these values as it has already been done in wxGtkPrinter::BeginPrint. 
 984             startPage 
= range
[0].start 
+ 1; 
 985             endPage 
= range
[0].end 
+ 1; 
 992         case GTK_PRINT_PAGES_ALL
: 
 999     if(numPageToDraw 
== startPage
) 
1001         if (!printout
->OnBeginDocument(startPage
, endPage
)) 
1003             wxLogError(_("Could not start printing.")); 
1004             sm_lastError 
= wxPRINTER_ERROR
; 
1008     // The app can render the page numPageToDraw. 
1009     if (printout
->HasPage(numPageToDraw
)) 
1012         printout
->OnPrintPage(numPageToDraw
); 
1017     if(numPageToDraw 
== endPage
) 
1019         printout
->OnEndDocument(); 
1023 wxDC
* wxGtkPrinter::PrintDialog( wxWindow 
*parent 
) 
1025     wxGtkPrintDialog 
dialog( parent
, &m_printDialogData 
); 
1028     dialog
.SetPrintDC(m_dc
); 
1030     dialog
.SetShowDialog(m_showDialog
); 
1032     ret 
= dialog
.ShowModal(); 
1034     if (ret 
== wxID_CANCEL
) 
1036         sm_lastError 
= wxPRINTER_CANCELLED
; 
1041         sm_lastError 
= wxPRINTER_ERROR
; 
1042         wxFAIL_MSG(_("The print dialog returned an error.")); 
1046     m_printDialogData 
= dialog
.GetPrintDialogData(); 
1047     return new wxGtkPrintDC( m_printDialogData
.GetPrintData() ); 
1050 bool wxGtkPrinter::Setup( wxWindow 
*parent 
) 
1052     // Obsolete, for backward compatibility. 
1056 //----------------------------------------------------------------------------- 
1058 //----------------------------------------------------------------------------- 
1060 #define XLOG2DEV(x)     ((double)(LogicalToDeviceX(x)) * m_DEV2PS) 
1061 #define XLOG2DEVREL(x)  ((double)(LogicalToDeviceXRel(x)) * m_DEV2PS) 
1062 #define YLOG2DEV(x)     ((double)(LogicalToDeviceY(x)) * m_DEV2PS) 
1063 #define YLOG2DEVREL(x)  ((double)(LogicalToDeviceYRel(x)) * m_DEV2PS) 
1065 IMPLEMENT_CLASS(wxGtkPrintDC
, wxDC
) 
1067 wxGtkPrintDC::wxGtkPrintDC( const wxPrintData
& data 
) 
1071     wxGtkPrintNativeData 
*native 
= 
1072         (wxGtkPrintNativeData
*) m_printData
.GetNativeData(); 
1074     m_gpc 
= native
->GetPrintContext(); 
1076     // RR: what does this do? 
1077     m_resolution 
= m_printData
.GetQuality(); // (int) gtk_print_context_get_dpi_x( m_gpc ); 
1078     if (m_resolution 
< 0)  
1079         m_resolution 
= (1 << (m_resolution
+4)) *150; 
1081     wxPrintf( "resolution %d\n", m_resolution 
); 
1083     m_PS2DEV 
= (double)m_resolution 
/ 72.0; 
1084     m_DEV2PS 
= 72.0 / (double)m_resolution
; 
1086     m_context 
= gtk_print_context_create_pango_context( m_gpc 
); 
1087     m_layout 
= gtk_print_context_create_pango_layout ( m_gpc 
); 
1088     m_fontdesc 
= pango_font_description_from_string( "Sans 12" ); 
1090     m_cairo 
= gtk_print_context_get_cairo_context ( m_gpc 
); 
1096     m_signX 
=  1;  // default x-axis left to right. 
1097     m_signY 
= 1;  // default y-axis bottom up -> top down. 
1099     // By default the origine of cairo contexte is in the upper left corner of the printable area. 
1100     // We need to translate it so that it is in the upper left corner of the paper (i.e. doesn't care about margins) 
1101     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
1103     ml 
= gtk_page_setup_get_left_margin (setup
, GTK_UNIT_POINTS
); 
1104     mt 
= gtk_page_setup_get_top_margin (setup
, GTK_UNIT_POINTS
); 
1105     gs_cairo
->cairo_translate(m_cairo
, -ml
, -mt
); 
1108 wxGtkPrintDC::~wxGtkPrintDC() 
1110     g_object_unref(m_context
); 
1111     g_object_unref(m_layout
); 
1114 bool wxGtkPrintDC::IsOk() const 
1116     return (m_gpc 
!= NULL
); 
1119 bool wxGtkPrintDC::DoFloodFill(wxCoord x1
, wxCoord y1
, const wxColour 
&col
, int style 
) 
1121     // We can't access the given coord as a cairo context is scalable, ie a coord doesn't mean anything in this context. 
1122     wxFAIL_MSG(_("not implemented")); 
1126 void wxGtkPrintDC::DoGradientFillConcentric(const wxRect
& rect
, const wxColour
& initialColour
, const wxColour
& destColour
, const wxPoint
& circleCenter
) 
1128     wxCoord xC 
= circleCenter
.x
; 
1129     wxCoord yC 
= circleCenter
.y
; 
1130     wxCoord xR 
= rect
.x
; 
1131     wxCoord yR 
= rect
.y
; 
1132     wxCoord w 
=  rect
.width
; 
1133     wxCoord h 
= rect
.height
; 
1135     double radius 
= sqrt((w
/2)*(w
/2)+(h
/2)*(h
/2)); 
1137     unsigned char redI 
= initialColour
.Red(); 
1138     unsigned char blueI 
= initialColour
.Blue(); 
1139     unsigned char greenI 
= initialColour
.Green(); 
1140     unsigned char alphaI 
= initialColour
.Alpha(); 
1141     unsigned char redD 
= destColour
.Red(); 
1142     unsigned char blueD 
= destColour
.Blue(); 
1143     unsigned char greenD 
= destColour
.Green(); 
1144     unsigned char alphaD 
= destColour
.Alpha(); 
1146     double redIPS 
= (double)(redI
) / 255.0; 
1147     double blueIPS 
= (double)(blueI
) / 255.0; 
1148     double greenIPS 
= (double)(greenI
) / 255.0; 
1149     double alphaIPS 
= (double)(alphaI
) / 255.0; 
1150     double redDPS 
= (double)(redD
) / 255.0; 
1151     double blueDPS 
= (double)(blueD
) / 255.0; 
1152     double greenDPS 
= (double)(greenD
) / 255.0; 
1153     double alphaDPS 
= (double)(alphaD
) / 255.0; 
1155     // Create a pattern with the gradient. 
1156     cairo_pattern_t
* gradient
; 
1157     gradient 
= gs_cairo
->cairo_pattern_create_radial (XLOG2DEV(xC
+xR
), YLOG2DEV(yC
+yR
), 0, XLOG2DEV(xC
+xR
), YLOG2DEV(yC
+yR
), radius 
* m_DEV2PS 
); 
1158     gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1159     gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1161     // Fill the rectangle with this pattern. 
1162     gs_cairo
->cairo_set_source(m_cairo
, gradient
); 
1163     gs_cairo
->cairo_rectangle (m_cairo
, XLOG2DEV(xR
), YLOG2DEV(yR
), XLOG2DEVREL(w
), YLOG2DEVREL(h
) ); 
1164     gs_cairo
->cairo_fill(m_cairo
); 
1166     gs_cairo
->cairo_pattern_destroy(gradient
); 
1168     CalcBoundingBox(xR
, yR
); 
1169     CalcBoundingBox(xR
+w
, yR
+h
); 
1172 void wxGtkPrintDC::DoGradientFillLinear(const wxRect
& rect
, const wxColour
& initialColour
, const wxColour
& destColour
, wxDirection nDirection
) 
1176     wxCoord w 
= rect
.width
; 
1177     wxCoord h 
= rect
.height
; 
1179     unsigned char redI 
= initialColour
.Red(); 
1180     unsigned char blueI 
= initialColour
.Blue(); 
1181     unsigned char greenI 
= initialColour
.Green(); 
1182     unsigned char alphaI 
= initialColour
.Alpha(); 
1183     unsigned char redD 
= destColour
.Red(); 
1184     unsigned char blueD 
= destColour
.Blue(); 
1185     unsigned char greenD 
= destColour
.Green(); 
1186     unsigned char alphaD 
= destColour
.Alpha(); 
1188     double redIPS 
= (double)(redI
) / 255.0; 
1189     double blueIPS 
= (double)(blueI
) / 255.0; 
1190     double greenIPS 
= (double)(greenI
) / 255.0; 
1191     double alphaIPS 
= (double)(alphaI
) / 255.0; 
1192     double redDPS 
= (double)(redD
) / 255.0; 
1193     double blueDPS 
= (double)(blueD
) / 255.0; 
1194     double greenDPS 
= (double)(greenD
) / 255.0; 
1195     double alphaDPS 
= (double)(alphaD
) / 255.0; 
1197     // Create a pattern with the gradient. 
1198     cairo_pattern_t
* gradient
; 
1199     gradient 
= gs_cairo
->cairo_pattern_create_linear (XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x
+w
), YLOG2DEV(y
)); 
1201     if (nDirection 
== wxWEST
) 
1203         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1204         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1207         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 0.0, redIPS
, greenIPS
, blueIPS
, alphaIPS
); 
1208         gs_cairo
->cairo_pattern_add_color_stop_rgba (gradient
, 1.0, redDPS
, greenDPS
, blueDPS
, alphaDPS
); 
1211     // Fill the rectangle with this pattern. 
1212     gs_cairo
->cairo_set_source(m_cairo
, gradient
); 
1213     gs_cairo
->cairo_rectangle (m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEVREL(w
), YLOG2DEVREL(h
) ); 
1214     gs_cairo
->cairo_fill(m_cairo
); 
1216     gs_cairo
->cairo_pattern_destroy(gradient
); 
1218     CalcBoundingBox(x
, y
); 
1219     CalcBoundingBox(x
+w
, y
+h
); 
1222 bool wxGtkPrintDC::DoGetPixel(wxCoord x1
, wxCoord y1
, wxColour 
*col
) const 
1224     // We can't access the given coord as a cairo context is scalable, ie a coord doesn't mean anything in this context. 
1225     wxFAIL_MSG(_("not implemented")); 
1229 void wxGtkPrintDC::DoDrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
) 
1231     if  (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
1234     gs_cairo
->cairo_move_to ( m_cairo
, XLOG2DEV(x1
), YLOG2DEV(y1
) ); 
1235     gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
1236     gs_cairo
->cairo_stroke ( m_cairo 
); 
1238     CalcBoundingBox( x1
, y1 
); 
1239     CalcBoundingBox( x2
, y2 
); 
1242 void wxGtkPrintDC::DoCrossHair(wxCoord x
, wxCoord y
) 
1249     gs_cairo
->cairo_move_to (m_cairo
, XLOG2DEV(x
), 0); 
1250     gs_cairo
->cairo_line_to (m_cairo
, XLOG2DEV(x
), YLOG2DEVREL(h
)); 
1251     gs_cairo
->cairo_move_to (m_cairo
, 0, YLOG2DEV(y
)); 
1252     gs_cairo
->cairo_line_to (m_cairo
, XLOG2DEVREL(w
), YLOG2DEV(y
)); 
1254     gs_cairo
->cairo_stroke (m_cairo
); 
1255     CalcBoundingBox( 0, 0 ); 
1256     CalcBoundingBox( w
, h 
); 
1259 void wxGtkPrintDC::DoDrawArc(wxCoord x1
,wxCoord y1
,wxCoord x2
,wxCoord y2
,wxCoord xc
,wxCoord yc
) 
1261     double dx 
= x1 
- xc
; 
1262     double dy 
= y1 
- yc
; 
1263     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
1265     double alpha1
, alpha2
; 
1266     if (x1 
== x2 
&& y1 
== y2
) 
1274         alpha1 
= alpha2 
= 0.0; 
1278         alpha1 
= (x1 
- xc 
== 0) ? 
1279             (y1 
- yc 
< 0) ? 90.0 : -90.0 : 
1280             atan2(double(y1
-yc
), double(x1
-xc
)) * RAD2DEG
; 
1281         alpha2 
= (x2 
- xc 
== 0) ? 
1282             (y2 
- yc 
< 0) ? 90.0 : -90.0 : 
1283             atan2(double(y2
-yc
), double(x2
-xc
)) * RAD2DEG
; 
1285         while (alpha1 
<= 0)   alpha1 
+= 360; 
1286         while (alpha2 
<= 0)   alpha2 
+= 360; // adjust angles to be between. 
1287         while (alpha1 
> 360)  alpha1 
-= 360; // 0 and 360 degree. 
1288         while (alpha2 
> 360)  alpha2 
-= 360; 
1294     gs_cairo
->cairo_new_path(m_cairo
); 
1296     gs_cairo
->cairo_arc_negative ( m_cairo
, XLOG2DEV(xc
), YLOG2DEV(yc
), XLOG2DEVREL((int)radius
), alpha1
, alpha2
); 
1297     gs_cairo
->cairo_line_to(m_cairo
, XLOG2DEV(xc
), YLOG2DEV(yc
)); 
1298     gs_cairo
->cairo_close_path (m_cairo
); 
1300     SetBrush( m_brush 
); 
1301     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1304     gs_cairo
->cairo_stroke( m_cairo 
); 
1306     CalcBoundingBox (x1
, y1
); 
1307     CalcBoundingBox (xc
, yc
); 
1308     CalcBoundingBox (x2
, y2
); 
1311 void wxGtkPrintDC::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
) 
1313     gs_cairo
->cairo_save( m_cairo 
); 
1315     gs_cairo
->cairo_new_path(m_cairo
); 
1317     gs_cairo
->cairo_translate( m_cairo
, XLOG2DEV((wxCoord
) (x 
+ w 
/ 2.)), XLOG2DEV((wxCoord
) (y 
+ h 
/ 2.)) ); 
1318     double scale 
= (double)YLOG2DEVREL(h
) / (double) XLOG2DEVREL(w
); 
1319     gs_cairo
->cairo_scale( m_cairo
, 1.0, scale 
); 
1321     gs_cairo
->cairo_arc_negative ( m_cairo
, 0, 0, XLOG2DEVREL(w
/2), -sa
*DEG2RAD
, -ea
*DEG2RAD
); 
1324     gs_cairo
->cairo_stroke_preserve( m_cairo 
); 
1326     gs_cairo
->cairo_line_to(m_cairo
, 0,0); 
1328     SetBrush( m_brush 
); 
1329     gs_cairo
->cairo_fill( m_cairo 
); 
1331     gs_cairo
->cairo_restore( m_cairo 
); 
1333     CalcBoundingBox( x
, y
); 
1334     CalcBoundingBox( x
+w
, y
+h 
); 
1337 void wxGtkPrintDC::DoDrawPoint(wxCoord x
, wxCoord y
) 
1339     if  (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
1343     gs_cairo
->cairo_move_to ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1344     gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1345     gs_cairo
->cairo_stroke ( m_cairo 
); 
1347     CalcBoundingBox( x
, y 
); 
1350 void wxGtkPrintDC::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
) 
1352     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
1359     for ( i 
=0; i
<n 
; i
++ ) 
1360         CalcBoundingBox( points
[i
].x
+xoffset
, points
[i
].y
+yoffset
); 
1362     gs_cairo
->cairo_move_to ( m_cairo
, XLOG2DEV(points
[0].x
+xoffset
), YLOG2DEV(points
[0].y
+yoffset
) ); 
1364     for (i 
= 1; i 
< n
; i
++) 
1365         gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEV(points
[i
].x
+xoffset
), YLOG2DEV(points
[i
].y
+yoffset
) ); 
1367     gs_cairo
->cairo_stroke ( m_cairo
); 
1370 void wxGtkPrintDC::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
) 
1374     gs_cairo
->cairo_save(m_cairo
); 
1375     if (fillStyle 
== wxWINDING_RULE
) 
1376         gs_cairo
->cairo_set_fill_rule( m_cairo
, CAIRO_FILL_RULE_WINDING
); 
1378         gs_cairo
->cairo_set_fill_rule( m_cairo
, CAIRO_FILL_RULE_EVEN_ODD
); 
1380     int x 
= points
[0].x 
+ xoffset
; 
1381     int y 
= points
[0].y 
+ yoffset
; 
1382     gs_cairo
->cairo_new_path(m_cairo
); 
1383     gs_cairo
->cairo_move_to( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1385     for (i 
= 1; i 
< n
; i
++) 
1387         int x 
= points
[i
].x 
+ xoffset
; 
1388         int y 
= points
[i
].y 
+ yoffset
; 
1389         gs_cairo
->cairo_line_to( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
1391     gs_cairo
->cairo_close_path(m_cairo
); 
1393     SetBrush( m_brush 
); 
1394     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1397     gs_cairo
->cairo_stroke( m_cairo 
); 
1399     CalcBoundingBox( x
, y 
); 
1401     gs_cairo
->cairo_restore(m_cairo
); 
1404 void wxGtkPrintDC::DoDrawPolyPolygon(int n
, int count
[], wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
) 
1406     wxDC::DoDrawPolyPolygon( n
, count
, points
, xoffset
, yoffset
, fillStyle 
); 
1409 void wxGtkPrintDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1411     gs_cairo
->cairo_new_path(m_cairo
); 
1412     gs_cairo
->cairo_rectangle ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
1414     SetBrush( m_brush 
); 
1415     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1418     gs_cairo
->cairo_stroke( m_cairo 
); 
1420     CalcBoundingBox( x
, y 
); 
1421     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1424 void wxGtkPrintDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
) 
1426     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
1428     wxCoord dd 
= 2 * (wxCoord
) radius
; 
1429     if (dd 
> width
) dd 
= width
; 
1430     if (dd 
> height
) dd 
= height
; 
1433     wxCoord rad 
= (wxCoord
) radius
; 
1435     gs_cairo
->cairo_new_path(m_cairo
); 
1436     gs_cairo
->cairo_move_to(m_cairo
,XLOG2DEV(x 
+ rad
),YLOG2DEV(y
)); 
1437     gs_cairo
->cairo_curve_to(m_cairo
, 
1438                                 XLOG2DEV(x 
+ rad
),YLOG2DEV(y
), 
1439                                 XLOG2DEV(x
),YLOG2DEV(y
), 
1440                                 XLOG2DEV(x
),YLOG2DEV(y 
+ rad
)); 
1441     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEV(x
),YLOG2DEV(y 
+ height 
- rad
)); 
1442     gs_cairo
->cairo_curve_to(m_cairo
, 
1443                                 XLOG2DEV(x
),YLOG2DEV(y 
+ height 
- rad
), 
1444                                 XLOG2DEV(x
),YLOG2DEV(y 
+ height
), 
1445                                 XLOG2DEV(x 
+ rad
),YLOG2DEV(y 
+ height
)); 
1446     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEV(x 
+ width 
- rad
),YLOG2DEV(y 
+ height
)); 
1447     gs_cairo
->cairo_curve_to(m_cairo
, 
1448                                 XLOG2DEV(x 
+ width 
- rad
),YLOG2DEV(y 
+ height
), 
1449                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ height
), 
1450                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ height 
- rad
)); 
1451     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ rad
)); 
1452     gs_cairo
->cairo_curve_to(m_cairo
, 
1453                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y 
+ rad
), 
1454                                 XLOG2DEV(x 
+ width
),YLOG2DEV(y
), 
1455                                 XLOG2DEV(x 
+ width 
- rad
),YLOG2DEV(y
)); 
1456     gs_cairo
->cairo_line_to(m_cairo
,XLOG2DEV(x 
+ rad
),YLOG2DEV(y
)); 
1457     gs_cairo
->cairo_close_path(m_cairo
); 
1460     gs_cairo
->cairo_fill_preserve(m_cairo
); 
1463     gs_cairo
->cairo_stroke(m_cairo
); 
1465     CalcBoundingBox(x
,y
); 
1466     CalcBoundingBox(x
+width
,y
+height
); 
1469 void wxGtkPrintDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1471     gs_cairo
->cairo_save (m_cairo
); 
1473     gs_cairo
->cairo_new_path(m_cairo
); 
1475     gs_cairo
->cairo_translate (m_cairo
, XLOG2DEV((wxCoord
) (x 
+ width 
/ 2.)), YLOG2DEV((wxCoord
) (y 
+ height 
/ 2.))); 
1476     gs_cairo
->cairo_scale(m_cairo
, 1, (double)YLOG2DEVREL(height
)/(double)XLOG2DEVREL(width
)); 
1477     gs_cairo
->cairo_arc ( m_cairo
, 0, 0, XLOG2DEVREL(width
/2), 0, 2 * M_PI
); 
1479     SetBrush( m_brush 
); 
1480     gs_cairo
->cairo_fill_preserve( m_cairo 
); 
1483     gs_cairo
->cairo_stroke( m_cairo 
); 
1485     CalcBoundingBox( x
, y 
); 
1486     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1488     gs_cairo
->cairo_restore (m_cairo
); 
1492 void wxGtkPrintDC::DoDrawSpline(wxList 
*points
) 
1496     double c
, d
, x1
, y1
, x2
, y2
, x3
, y3
; 
1499     wxList::compatibility_iterator node 
= points
->GetFirst(); 
1500     p 
= (wxPoint 
*)node
->GetData(); 
1504     node 
= node
->GetNext(); 
1505     p 
= (wxPoint 
*)node
->GetData(); 
1509          (double)(x1 
+ c
) / 2; 
1511          (double)(y1 
+ d
) / 2; 
1513     gs_cairo
->cairo_new_path( m_cairo 
); 
1514     gs_cairo
->cairo_move_to( m_cairo
, XLOG2DEV((wxCoord
)x1
), YLOG2DEV((wxCoord
)y1
) ); 
1515     gs_cairo
->cairo_line_to( m_cairo
, XLOG2DEV((wxCoord
)x3
), YLOG2DEV((wxCoord
)y3
) ); 
1517     CalcBoundingBox( (wxCoord
)x1
, (wxCoord
)y1 
); 
1518     CalcBoundingBox( (wxCoord
)x3
, (wxCoord
)y3 
); 
1520     node 
= node
->GetNext(); 
1523         q 
= (wxPoint 
*)node
->GetData(); 
1531         x3 
= (double)(x2 
+ c
) / 2; 
1532         y3 
= (double)(y2 
+ d
) / 2; 
1534         gs_cairo
->cairo_curve_to(m_cairo
, 
1535             XLOG2DEV((wxCoord
)x1
), YLOG2DEV((wxCoord
)y1
), 
1536             XLOG2DEV((wxCoord
)x2
), YLOG2DEV((wxCoord
)y2
), 
1537             XLOG2DEV((wxCoord
)x3
), YLOG2DEV((wxCoord
)y3
) ); 
1539         CalcBoundingBox( (wxCoord
)x1
, (wxCoord
)y1 
); 
1540         CalcBoundingBox( (wxCoord
)x3
, (wxCoord
)y3 
); 
1542         node 
= node
->GetNext(); 
1545     gs_cairo
->cairo_line_to ( m_cairo
, XLOG2DEV((wxCoord
)c
), YLOG2DEV((wxCoord
)d
) ); 
1547     gs_cairo
->cairo_stroke( m_cairo 
); 
1549 #endif // wxUSE_SPLINES 
1551 bool wxGtkPrintDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
, 
1552             wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, int rop
, bool useMask
, 
1553             wxCoord xsrcMask
, wxCoord ysrcMask
) 
1555     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1557     // Blit into a bitmap. 
1558     wxBitmap 
bitmap( width
, height 
); 
1560     memDC
.SelectObject(bitmap
); 
1561     memDC
.Blit(0, 0, width
, height
, source
, xsrc
, ysrc
, rop
); 
1562     memDC
.SelectObject(wxNullBitmap
); 
1564     // Draw bitmap. scaling and positioning is done there. 
1565     DrawBitmap( bitmap
, xdest
, ydest
, useMask 
); 
1570 void wxGtkPrintDC::DoDrawIcon( const wxIcon
& icon
, wxCoord x
, wxCoord y 
) 
1572     DoDrawBitmap( icon
, x
, y
, true ); 
1575 void wxGtkPrintDC::DoDrawBitmap( const wxBitmap
& bitmap
, wxCoord x
, wxCoord y
, bool useMask 
) 
1577     wxCHECK_RET( bitmap
.IsOk(), wxT("Invalid bitmap in wxGtkPrintDC::DoDrawBitmap")); 
1579     cairo_surface_t
* surface
; 
1580     x 
= wxCoord(XLOG2DEV(x
)); 
1581     y 
= wxCoord(YLOG2DEV(y
)); 
1582     int bw 
= bitmap
.GetWidth(); 
1583     int bh 
= bitmap
.GetHeight(); 
1584     wxBitmap bmpSource 
= bitmap
;  // we need a non-const instance. 
1585     unsigned char* buffer 
= new unsigned char[bw
*bh
*4]; 
1586     wxUint32
* data 
= (wxUint32
*)buffer
; 
1588     wxMask 
*mask 
= NULL
; 
1589     if (useMask
) mask 
= bmpSource
.GetMask(); 
1591     // Create a surface object and copy the bitmap pixel data to it. If the image has alpha (or a mask represented as alpha) 
1592     // then we'll use a different format and iterator than if it doesn't. 
1593     if (bmpSource
.HasAlpha() || mask
) 
1595         surface 
= gs_cairo
->cairo_image_surface_create_for_data( 
1596             buffer
, CAIRO_FORMAT_ARGB32
, bw
, bh
, bw
*4); 
1597         wxAlphaPixelData 
pixData(bmpSource
, wxPoint(0,0), wxSize(bw
, bh
)); 
1598         wxCHECK_RET( pixData
, wxT("Failed to gain raw access to bitmap data.")); 
1600         wxAlphaPixelData::Iterator 
p(pixData
); 
1602         for (y
=0; y
<bh
; y
++) 
1604             wxAlphaPixelData::Iterator rowStart 
= p
; 
1605             for (x
=0; x
<bw
; x
++) 
1607                 // Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity, 
1608                 // with alpha in the upper 8 bits, then red, then green, then 
1609                 // blue. The 32-bit quantities are stored native-endian. 
1610                 // Pre-multiplied alpha is used. 
1611                 unsigned char alpha 
= p
.Alpha(); 
1613                 if (!bmpSource
.HasAlpha() && mask
) 
1619                     *data 
= ( alpha                  
<< 24 
1620                               | (p
.Red() * alpha
/255)    << 16 
1621                               | (p
.Green() * alpha
/255)  <<  8 
1622                               | (p
.Blue() * alpha
/255) ); 
1627             p
.OffsetY(pixData
, 1); 
1632         surface 
= gs_cairo
->cairo_image_surface_create_for_data( 
1633             buffer
, CAIRO_FORMAT_RGB24
, bw
, bh
, bw
*4); 
1634         wxNativePixelData 
pixData(bmpSource
, wxPoint(0,0), wxSize(bw
, bh
)); 
1635         wxCHECK_RET( pixData
, wxT("Failed to gain raw access to bitmap data.")); 
1637         wxNativePixelData::Iterator 
p(pixData
); 
1639         for (y
=0; y
<bh
; y
++) 
1641             wxNativePixelData::Iterator rowStart 
= p
; 
1642             for (x
=0; x
<bw
; x
++) 
1644                 // Each pixel in CAIRO_FORMAT_RGB24 is a 32-bit quantity, with 
1645                 // the upper 8 bits unused. Red, Green, and Blue are stored in 
1646                 // the remaining 24 bits in that order.  The 32-bit quantities 
1647                 // are stored native-endian. 
1648                 *data 
= ( p
.Red() << 16 | p
.Green() << 8 | p
.Blue() ); 
1653             p
.OffsetY(pixData
, 1); 
1658     gs_cairo
->cairo_save(m_cairo
); 
1660     // Prepare to draw the image. 
1661     gs_cairo
->cairo_translate(m_cairo
, x
, y
); 
1664     cairo_filter_t filter 
= CAIRO_FILTER_BILINEAR
; 
1665     cairo_pattern_t
* pattern 
= cairo_pattern_create_for_surface(surface
); 
1666     cairo_pattern_set_filter(pattern
,filter
); 
1667     wxDouble scaleX 
= (wxDouble
) XLOG2DEVREL(bw
) / (wxDouble
) bw
; 
1668     wxDouble scaleY 
= (wxDouble
) YLOG2DEVREL(bh
) / (wxDouble
) bh
; 
1669     cairo_scale(m_cairo
, scaleX
, scaleY
); 
1671     gs_cairo
->cairo_set_source(m_cairo
, pattern
); 
1672     // Use the original size here since the context is scaled already. 
1673     gs_cairo
->cairo_rectangle(m_cairo
, 0, 0, bw
, bh
); 
1674     // Fill the rectangle using the pattern. 
1675     gs_cairo
->cairo_fill(m_cairo
); 
1678     gs_cairo
->cairo_pattern_destroy(pattern
); 
1679     gs_cairo
->cairo_surface_destroy(surface
); 
1682     CalcBoundingBox(0,0); 
1683     CalcBoundingBox(bw
,bh
); 
1685     gs_cairo
->cairo_restore(m_cairo
); 
1688 void wxGtkPrintDC::DoDrawText(const wxString
& text
, wxCoord x
, wxCoord y 
) 
1690     DoDrawRotatedText( text
, x
, y
, 0.0 ); 
1693 void wxGtkPrintDC::DoDrawRotatedText(const wxString
& text
, wxCoord x
, wxCoord y
, double angle
) 
1695     double xx 
= XLOG2DEV(x
); 
1696     double yy 
= YLOG2DEV(y
); 
1700     bool underlined 
= m_font
.Ok() && m_font
.GetUnderlined(); 
1702 // FIXME-UTF8: wouldn't be needed if utf8_str() always returned a buffer 
1703 #if wxUSE_UNICODE_UTF8 
1704     const char *data 
= text
.utf8_str(); 
1706     const wxCharBuffer data 
= text
.utf8_str(); 
1709     size_t datalen 
= strlen(data
); 
1710     pango_layout_set_text( m_layout
, data
, datalen
); 
1714         PangoAttrList 
*attrs 
= pango_attr_list_new(); 
1715         PangoAttribute 
*a 
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
); 
1717         a
->end_index 
= datalen
; 
1718         pango_attr_list_insert(attrs
, a
); 
1719         pango_layout_set_attributes(m_layout
, attrs
); 
1720         pango_attr_list_unref(attrs
); 
1723     if (m_textForegroundColour
.Ok()) 
1725         unsigned char red 
= m_textForegroundColour
.Red(); 
1726         unsigned char blue 
= m_textForegroundColour
.Blue(); 
1727         unsigned char green 
= m_textForegroundColour
.Green(); 
1728         unsigned char alpha 
= m_textForegroundColour
.Alpha(); 
1730         if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1732             double redPS 
= (double)(red
) / 255.0; 
1733             double bluePS 
= (double)(blue
) / 255.0; 
1734             double greenPS 
= (double)(green
) / 255.0; 
1735             double alphaPS 
= (double)(alpha
) / 255.0; 
1737             gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1740             m_currentBlue 
= blue
; 
1741             m_currentGreen 
= green
; 
1742             m_currentAlpha 
= alpha
; 
1748     // Scale font description. 
1749     gint oldSize 
= pango_font_description_get_size( m_fontdesc 
); 
1750     double size 
= oldSize
; 
1751     size 
= size 
* m_scaleX
; 
1752     pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1754     // Actually apply scaled font. 
1755     pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1757     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1759         if ( m_backgroundMode 
== wxSOLID 
) 
1761             unsigned char red 
= m_textBackgroundColour
.Red(); 
1762             unsigned char blue 
= m_textBackgroundColour
.Blue(); 
1763             unsigned char green 
= m_textBackgroundColour
.Green(); 
1764             unsigned char alpha 
= m_textBackgroundColour
.Alpha(); 
1766             double redPS 
= (double)(red
) / 255.0; 
1767             double bluePS 
= (double)(blue
) / 255.0; 
1768             double greenPS 
= (double)(green
) / 255.0; 
1769             double alphaPS 
= (double)(alpha
) / 255.0; 
1771             gs_cairo
->cairo_save(m_cairo
); 
1772             gs_cairo
->cairo_translate(m_cairo
, xx
, yy
); 
1773             gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1774             gs_cairo
->cairo_rotate(m_cairo
,angle
*DEG2RAD
); 
1775             gs_cairo
->cairo_rectangle(m_cairo
, 0, 0, w
, h
);   // still in cairo units 
1776             gs_cairo
->cairo_fill(m_cairo
); 
1777             gs_cairo
->cairo_restore(m_cairo
); 
1781     gs_cairo
->cairo_move_to (m_cairo
, xx
, yy
); 
1783     gs_cairo
->cairo_save( m_cairo 
); 
1785     if (fabs(angle
) > 0.00001) 
1786         gs_cairo
->cairo_rotate( m_cairo
, angle
*DEG2RAD 
); 
1788     gs_cairo
->pango_cairo_update_layout (m_cairo
, m_layout
); 
1789     gs_cairo
->pango_cairo_show_layout (m_cairo
, m_layout
); 
1791     gs_cairo
->cairo_restore( m_cairo 
); 
1795         // Undo underline attributes setting 
1796         pango_layout_set_attributes(m_layout
, NULL
); 
1799     // Reset unscaled size. 
1800     pango_font_description_set_size( m_fontdesc
, oldSize 
); 
1802     // Actually apply unscaled font. 
1803     pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1805     // Back to device units: 
1806     CalcBoundingBox (x
, y
); 
1807     CalcBoundingBox (x 
+ w
, y 
+ h
); 
1810 void wxGtkPrintDC::Clear() 
1812 // Clear does nothing for printing, but keep the code 
1815     gs_cairo->cairo_save(m_cairo); 
1816     gs_cairo->cairo_set_operator (m_cairo, CAIRO_OPERATOR_SOURCE); 
1817     SetBrush(m_backgroundBrush); 
1818     gs_cairo->cairo_paint(m_cairo); 
1819     gs_cairo->cairo_restore(m_cairo); 
1823 void wxGtkPrintDC::SetFont( const wxFont
& font 
) 
1830             pango_font_description_free( m_fontdesc 
); 
1832         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); // m_fontdesc is now set to device units 
1834         // Scale font description from device units to pango units 
1835         gint oldSize 
= pango_font_description_get_size( m_fontdesc 
);  
1836         double size 
= oldSize 
*m_DEV2PS
;                          // scale to cairo units 
1837         pango_font_description_set_size( m_fontdesc
, (gint
)size 
);    // apply to description 
1839         // Actually apply scaled font. 
1840         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1844 void wxGtkPrintDC::SetPen( const wxPen
& pen 
) 
1846     if (!pen
.Ok()) return; 
1850     double width 
= (double) m_pen
.GetWidth(); 
1851     if (width 
== 0) width 
= 0.1; 
1853     gs_cairo
->cairo_set_line_width( m_cairo
, (width 
* m_PS2DEV
) / m_scaleX 
); 
1854     static const double dotted
[] = {2.0, 5.0}; 
1855     static const double short_dashed
[] = {4.0, 4.0}; 
1856     static const double long_dashed
[] = {4.0, 8.0}; 
1857     static const double dotted_dashed
[] = {6.0, 6.0, 2.0, 6.0}; 
1859     switch (m_pen
.GetStyle()) 
1861         case wxDOT
:           gs_cairo
->cairo_set_dash( m_cairo
, dotted
, 2, 0 ); break; 
1862         case wxSHORT_DASH
:    gs_cairo
->cairo_set_dash( m_cairo
, short_dashed
, 2, 0 ); break; 
1863         case wxLONG_DASH
:     gs_cairo
->cairo_set_dash( m_cairo
, long_dashed
, 2, 0 ); break; 
1864         case wxDOT_DASH
:      gs_cairo
->cairo_set_dash( m_cairo
, dotted_dashed
, 4, 0 );  break; 
1868             int num 
= m_pen
.GetDashes (&wx_dashes
); 
1869             gdouble 
*g_dashes 
= g_new( gdouble
, num 
); 
1871             for (i 
= 0; i 
< num
; ++i
) 
1872                 g_dashes
[i
] = (gdouble
) wx_dashes
[i
]; 
1873             gs_cairo
->cairo_set_dash( m_cairo
, g_dashes
, num
, 0); 
1879         default:              gs_cairo
->cairo_set_dash( m_cairo
, NULL
, 0, 0 );   break; 
1882     switch (m_pen
.GetCap()) 
1884         case wxCAP_PROJECTING
:  gs_cairo
->cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_SQUARE
); break; 
1885         case wxCAP_BUTT
:        gs_cairo
->cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_BUTT
); break; 
1887         default:                gs_cairo
->cairo_set_line_cap (m_cairo
, CAIRO_LINE_CAP_ROUND
); break; 
1890     switch (m_pen
.GetJoin()) 
1892         case wxJOIN_BEVEL
:  gs_cairo
->cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_BEVEL
); break; 
1893         case wxJOIN_MITER
:  gs_cairo
->cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_MITER
); break; 
1895         default:            gs_cairo
->cairo_set_line_join (m_cairo
, CAIRO_LINE_JOIN_ROUND
); break; 
1898     unsigned char red 
= m_pen
.GetColour().Red(); 
1899     unsigned char blue 
= m_pen
.GetColour().Blue(); 
1900     unsigned char green 
= m_pen
.GetColour().Green(); 
1901     unsigned char alpha 
= m_pen
.GetColour().Alpha(); 
1903     if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1905         double redPS 
= (double)(red
) / 255.0; 
1906         double bluePS 
= (double)(blue
) / 255.0; 
1907         double greenPS 
= (double)(green
) / 255.0; 
1908         double alphaPS 
= (double)(alpha
) / 255.0; 
1910         gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1913         m_currentBlue 
= blue
; 
1914         m_currentGreen 
= green
; 
1915         m_currentAlpha 
= alpha
; 
1919 void wxGtkPrintDC::SetBrush( const wxBrush
& brush 
) 
1921     if (!brush
.Ok()) return; 
1925     if (m_brush
.GetStyle() == wxTRANSPARENT
) 
1927         gs_cairo
->cairo_set_source_rgba( m_cairo
, 0, 0, 0, 0 ); 
1936     unsigned char red 
= m_brush
.GetColour().Red(); 
1937     unsigned char blue 
= m_brush
.GetColour().Blue(); 
1938     unsigned char green 
= m_brush
.GetColour().Green(); 
1939     unsigned char alpha 
= m_brush
.GetColour().Alpha(); 
1941     double redPS 
= (double)(red
) / 255.0; 
1942     double bluePS 
= (double)(blue
) / 255.0; 
1943     double greenPS 
= (double)(green
) / 255.0; 
1944     double alphaPS 
= (double)(alpha
) / 255.0; 
1946     if (!(red 
== m_currentRed 
&& green 
== m_currentGreen 
&& blue 
== m_currentBlue 
&& alpha 
== m_currentAlpha
)) 
1948         gs_cairo
->cairo_set_source_rgba( m_cairo
, redPS
, greenPS
, bluePS
, alphaPS 
); 
1951         m_currentBlue 
= blue
; 
1952         m_currentGreen 
= green
; 
1953         m_currentAlpha 
= alpha
; 
1956     if (m_brush
.IsHatch()) 
1959         cairo_surface_t 
*surface
; 
1960         surface 
= gs_cairo
->cairo_surface_create_similar(gs_cairo
->cairo_get_target(m_cairo
),CAIRO_CONTENT_COLOR_ALPHA
,10,10); 
1961         cr 
= gs_cairo
->cairo_create(surface
); 
1962         gs_cairo
->cairo_set_line_cap(cr
, CAIRO_LINE_CAP_SQUARE
); 
1963         gs_cairo
->cairo_set_line_width(cr
, 1); 
1964         gs_cairo
->cairo_set_line_join(cr
,CAIRO_LINE_JOIN_MITER
); 
1966         switch (m_brush
.GetStyle()) 
1969                 gs_cairo
->cairo_move_to(cr
, 5, 0); 
1970                 gs_cairo
->cairo_line_to(cr
, 5, 10); 
1971                 gs_cairo
->cairo_move_to(cr
, 0, 5); 
1972                 gs_cairo
->cairo_line_to(cr
, 10, 5); 
1974             case wxBDIAGONAL_HATCH
: 
1975                 gs_cairo
->cairo_move_to(cr
, 0, 10); 
1976                 gs_cairo
->cairo_line_to(cr
, 10, 0); 
1978             case wxFDIAGONAL_HATCH
: 
1979                 gs_cairo
->cairo_move_to(cr
, 0, 0); 
1980                 gs_cairo
->cairo_line_to(cr
, 10, 10); 
1982             case wxCROSSDIAG_HATCH
: 
1983                 gs_cairo
->cairo_move_to(cr
, 0, 0); 
1984                 gs_cairo
->cairo_line_to(cr
, 10, 10); 
1985                 gs_cairo
->cairo_move_to(cr
, 10, 0); 
1986                 gs_cairo
->cairo_line_to(cr
, 0, 10); 
1988             case wxHORIZONTAL_HATCH
: 
1989                 gs_cairo
->cairo_move_to(cr
, 0, 5); 
1990                 gs_cairo
->cairo_line_to(cr
, 10, 5); 
1992             case wxVERTICAL_HATCH
: 
1993                 gs_cairo
->cairo_move_to(cr
, 5, 0); 
1994                 gs_cairo
->cairo_line_to(cr
, 5, 10); 
1997                 wxFAIL_MSG(_("Couldn't get hatch style from wxBrush.")); 
2000         gs_cairo
->cairo_set_source_rgba(cr
, redPS
, greenPS
, bluePS
, alphaPS
); 
2001         gs_cairo
->cairo_stroke (cr
); 
2003         gs_cairo
->cairo_destroy(cr
); 
2004         cairo_pattern_t 
* pattern 
= gs_cairo
->cairo_pattern_create_for_surface (surface
); 
2005         gs_cairo
->cairo_surface_destroy(surface
); 
2006         gs_cairo
->cairo_pattern_set_extend (pattern
, CAIRO_EXTEND_REPEAT
); 
2007         gs_cairo
->cairo_set_source(m_cairo
, pattern
); 
2008         gs_cairo
->cairo_pattern_destroy(pattern
); 
2012 void wxGtkPrintDC::SetLogicalFunction( int function 
) 
2014     if (function 
== wxCLEAR
) 
2015         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_CLEAR
); 
2016     else if (function 
== wxOR
) 
2017         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_OUT
); 
2018     else if (function 
== wxNO_OP
) 
2019         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_DEST
); 
2020     else if (function 
== wxAND
) 
2021         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_ADD
); 
2022     else if (function 
== wxSET
) 
2023         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_SATURATE
); 
2024     else if (function 
== wxXOR
) 
2025         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_XOR
); 
2026     else // wxCOPY or anything else. 
2027         gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_SOURCE
); 
2030 void wxGtkPrintDC::SetBackground( const wxBrush
& brush 
) 
2032     m_backgroundBrush 
= brush
; 
2033     gs_cairo
->cairo_save(m_cairo
); 
2034     gs_cairo
->cairo_set_operator (m_cairo
, CAIRO_OPERATOR_DEST_OVER
); 
2036     SetBrush(m_backgroundBrush
); 
2037     gs_cairo
->cairo_paint(m_cairo
); 
2038     gs_cairo
->cairo_restore(m_cairo
); 
2041 void wxGtkPrintDC::SetBackgroundMode(int mode
) 
2043     if (mode 
== wxSOLID
) m_backgroundMode 
= wxSOLID
; 
2044     else m_backgroundMode 
= wxTRANSPARENT
; 
2047 void wxGtkPrintDC::DoSetClippingRegion(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
2049     gs_cairo
->cairo_rectangle ( m_cairo
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
2050     gs_cairo
->cairo_clip(m_cairo
); 
2053 void wxGtkPrintDC::DestroyClippingRegion() 
2055     gs_cairo
->cairo_reset_clip(m_cairo
); 
2058 bool wxGtkPrintDC::StartDoc(const wxString
& message
) 
2063 void wxGtkPrintDC::EndDoc() 
2068 void wxGtkPrintDC::StartPage() 
2073 void wxGtkPrintDC::EndPage() 
2078 wxCoord 
wxGtkPrintDC::GetCharHeight() const 
2080     pango_layout_set_text( m_layout
, "H", 1 ); 
2083     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2085     return wxRound( h 
* m_PS2DEV 
); 
2088 wxCoord 
wxGtkPrintDC::GetCharWidth() const 
2090     pango_layout_set_text( m_layout
, "H", 1 ); 
2093     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2095     return wxRound( w 
* m_PS2DEV 
); 
2098 void wxGtkPrintDC::DoGetTextExtent(const wxString
& string
, wxCoord 
*width
, wxCoord 
*height
, 
2100                      wxCoord 
*externalLeading
, 
2101                      const wxFont 
*theFont 
) const 
2109     if ( externalLeading 
) 
2110         *externalLeading 
= 0; 
2117     // Set layout's text 
2118     // FIXME-UTF8: wouldn't be needed if utf8_str() always returned a buffer 
2119 #if wxUSE_UNICODE_UTF8 
2120     const char *dataUTF8 
= string
.utf8_str(); 
2122     const wxCharBuffer dataUTF8 
= string
.utf8_str(); 
2125     PangoFontDescription 
*desc 
= m_fontdesc
; 
2126     if (theFont
) desc 
= theFont
->GetNativeFontInfo()->description
; 
2128     gint oldSize 
= pango_font_description_get_size( desc 
); 
2129     double size 
= oldSize
; 
2130     size 
= size 
* m_scaleY
; 
2131     pango_font_description_set_size( desc
, (gint
)size 
); 
2133     // apply scaled font 
2134     pango_layout_set_font_description( m_layout
, desc 
); 
2136     pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) ); 
2139     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
2142         *width 
= wxRound( (double)w 
/ m_scaleX 
* m_PS2DEV 
); 
2144         *height 
= wxRound( (double)h 
/ m_scaleY 
* m_PS2DEV 
); 
2148         PangoLayoutIter 
*iter 
= pango_layout_get_iter(m_layout
); 
2149         int baseline 
= pango_layout_iter_get_baseline(iter
); 
2150         pango_layout_iter_free(iter
); 
2151         *descent 
= wxRound( (h 
- PANGO_PIXELS(baseline
)) * m_PS2DEV 
); 
2154     // Reset unscaled size. 
2155     pango_font_description_set_size( desc
, oldSize 
); 
2157     // Reset unscaled font. 
2158     pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
2161 void wxGtkPrintDC::DoGetSize(int* width
, int* height
) const 
2163     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
2166         *width 
= wxRound( gtk_page_setup_get_paper_width( setup
, GTK_UNIT_POINTS 
) * m_PS2DEV 
); 
2168         *height 
= wxRound( gtk_page_setup_get_paper_height( setup
, GTK_UNIT_POINTS 
) * m_PS2DEV 
); 
2171 void wxGtkPrintDC::DoGetSizeMM(int *width
, int *height
) const 
2173     GtkPageSetup 
*setup 
= gtk_print_context_get_page_setup( m_gpc 
); 
2176         *width 
= wxRound( gtk_page_setup_get_paper_width( setup
, GTK_UNIT_MM 
) ); 
2178         *height 
= wxRound( gtk_page_setup_get_paper_height( setup
, GTK_UNIT_MM 
) ); 
2181 wxSize 
wxGtkPrintDC::GetPPI() const 
2183     return wxSize( (int)m_resolution
, (int)m_resolution 
); 
2186 void wxGtkPrintDC::SetPrintData(const wxPrintData
& data
) 
2191 void wxGtkPrintDC::SetResolution(int ppi
) 
2193     // We can't change ppi of the GtkPrintContext. 
2194     // TODO: should we really support this? 
2197 int wxGtkPrintDC::GetResolution() 
2199     return m_resolution
; 
2202 // ---------------------------------------------------------------------------- 
2204 // ---------------------------------------------------------------------------- 
2206 IMPLEMENT_CLASS(wxGtkPrintPreview
, wxPrintPreviewBase
) 
2208 void wxGtkPrintPreview::Init(wxPrintout 
* WXUNUSED(printout
), 
2209                                     wxPrintout 
* WXUNUSED(printoutForPrinting
)) 
2214 wxGtkPrintPreview::wxGtkPrintPreview(wxPrintout 
*printout
, 
2215                                                    wxPrintout 
*printoutForPrinting
, 
2216                                                    wxPrintDialogData 
*data
) 
2217                         : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
2219     Init(printout
, printoutForPrinting
); 
2222 wxGtkPrintPreview::wxGtkPrintPreview(wxPrintout 
*printout
, 
2223                                                    wxPrintout 
*printoutForPrinting
, 
2225                         : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
2227     Init(printout
, printoutForPrinting
); 
2230 wxGtkPrintPreview::~wxGtkPrintPreview() 
2234 bool wxGtkPrintPreview::Print(bool interactive
) 
2236     if (!m_printPrintout
) 
2239     wxPrinter 
printer(& m_printDialogData
); 
2240     return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
); 
2243 void wxGtkPrintPreview::DetermineScaling() 
2245     wxPaperSize paperType 
= m_printDialogData
.GetPrintData().GetPaperId(); 
2247     wxPrintPaperType 
*paper 
= wxThePrintPaperDatabase
->FindPaperType(paperType
); 
2249         paper 
= wxThePrintPaperDatabase
->FindPaperType(wxPAPER_A4
); 
2253         wxSize ScreenPixels 
= wxGetDisplaySize(); 
2254         wxSize ScreenMM 
= wxGetDisplaySizeMM(); 
2256         m_previewPrintout
->SetPPIScreen( (int) ((ScreenPixels
.GetWidth() * 25.4) / ScreenMM
.GetWidth()), 
2257                                          (int) ((ScreenPixels
.GetHeight() * 25.4) / ScreenMM
.GetHeight()) ); 
2259         // TODO !!!!!!!!!!!!!!!       
2260         int resolution 
= 600; 
2261         m_previewPrintout
->SetPPIPrinter( resolution
, resolution 
); 
2263         // Get width and height in points (1/72th of an inch) 
2264         wxSize 
sizeDevUnits(paper
->GetSizeDeviceUnits()); 
2266         sizeDevUnits
.x 
= wxRound((double)sizeDevUnits
.x 
* (double)resolution 
/ 72.0); 
2267         sizeDevUnits
.y 
= wxRound((double)sizeDevUnits
.y 
* (double)resolution 
/ 72.0); 
2268         wxSize 
sizeTenthsMM(paper
->GetSize()); 
2269         wxSize 
sizeMM(sizeTenthsMM
.x 
/ 10, sizeTenthsMM
.y 
/ 10); 
2271         // If in landscape mode, we need to swap the width and height. 
2272         if ( m_printDialogData
.GetPrintData().GetOrientation() == wxLANDSCAPE 
) 
2274             m_pageWidth 
= sizeDevUnits
.y
; 
2275             m_pageHeight 
= sizeDevUnits
.x
; 
2276             m_previewPrintout
->SetPageSizeMM(sizeMM
.y
, sizeMM
.x
); 
2280             m_pageWidth 
= sizeDevUnits
.x
; 
2281             m_pageHeight 
= sizeDevUnits
.y
; 
2282             m_previewPrintout
->SetPageSizeMM(sizeMM
.x
, sizeMM
.y
); 
2284         m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
); 
2285         m_previewPrintout
->SetPaperRectPixels(wxRect(0, 0, m_pageWidth
, m_pageHeight
)); 
2287         // At 100%, the page should look about page-size on the screen. 
2288         m_previewScaleX 
= 0.8 * 72.0 / (double)resolution
; 
2289         m_previewScaleY 
= m_previewScaleX
;