]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/gnome/gprint.cpp
Start of run-time lookup of GNOME print libs.
[wxWidgets.git] / src / gtk1 / gnome / gprint.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gprint.cpp
3 // Author: Robert Roebling
4 // Purpose: Implement GNOME printing support
5 // Created: 09/20/04
6 // Copyright: Robert Roebling
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
11 #pragma implementation "gprint.h"
12 #endif
13
14 // For compilers that support precompilation, includes "wx/wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #include "wx/gtk/gnome/gprint.h"
22
23 #if wxUSE_LIBGNOMEPRINT
24
25 #include "math.h"
26
27 #include "wx/fontutil.h"
28 #include "wx/printdlg.h"
29 #include "wx/gtk/private.h"
30 #include "wx/module.h"
31 #include "wx/generic/prntdlgg.h"
32 #include "wx/dynlib.h"
33
34 #include <libgnomeprint/gnome-print.h>
35 #include <libgnomeprint/gnome-print-pango.h>
36 #include <libgnomeprint/gnome-print-config.h>
37 #include <libgnomeprintui/gnome-print-dialog.h>
38 #include <libgnomeprintui/gnome-print-job-preview.h>
39 #include <libgnomeprintui/gnome-print-paper-selector.h>
40
41 //----------------------------------------------------------------------------
42 // wxGnomePrintLibrary
43 //----------------------------------------------------------------------------
44
45 #define wxDL_METHOD_DEFINE( rettype, name, args, shortargs, defret ) \
46 typedef rettype (* name ## Type) args ; \
47 name ## Type pfn_ ## name; \
48 rettype name args \
49 { if (m_ok) return pfn_ ## name shortargs ; return defret; }
50
51 #define wxDL_METHOD_LOAD( lib, name, success ) \
52 pfn_ ## name = (name ## Type) lib->GetSymbol( wxT(#name), &success ); \
53 if (!success) return;
54
55 class wxGnomePrintLibrary
56 {
57 public:
58 wxGnomePrintLibrary();
59 ~wxGnomePrintLibrary();
60
61 bool IsOk();
62 void InitializeMethods();
63
64 private:
65 bool m_ok;
66 wxDynamicLibrary *m_gnome_print_lib;
67
68 public:
69 wxDL_METHOD_DEFINE( gint, gnome_print_newpath,
70 (GnomePrintContext *pc), (pc), 0 )
71 wxDL_METHOD_DEFINE( gint, gnome_print_moveto,
72 (GnomePrintContext *pc, gdouble x, gdouble y), (pc, x, y), 0 )
73 wxDL_METHOD_DEFINE( gint, gnome_print_lineto,
74 (GnomePrintContext *pc, gdouble x, gdouble y), (pc, x, y), 0 )
75 wxDL_METHOD_DEFINE( gint, gnome_print_curveto,
76 (GnomePrintContext *pc, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble x3, gdouble y3), (pc, x1, y1, x2, y2, x3, y3), 0 )
77 wxDL_METHOD_DEFINE( gint, gnome_print_closepath,
78 (GnomePrintContext *pc), (pc), 0 )
79 wxDL_METHOD_DEFINE( gint, gnome_print_stroke,
80 (GnomePrintContext *pc), (pc), 0 )
81 wxDL_METHOD_DEFINE( gint, gnome_print_fill,
82 (GnomePrintContext *pc), (pc), 0 )
83 wxDL_METHOD_DEFINE( gint, gnome_print_setrgbcolor,
84 (GnomePrintContext *pc, gdouble r, gdouble g, gdouble b), (pc, r, g, b), 0 )
85 wxDL_METHOD_DEFINE( gint, gnome_print_setlinewidth,
86 (GnomePrintContext *pc, gdouble width), (pc, width), 0 )
87 };
88
89 wxGnomePrintLibrary::wxGnomePrintLibrary()
90 {
91 wxLogNull log;
92 m_gnome_print_lib = new wxDynamicLibrary( wxT("libgnomeprint-2-2.so") );
93 m_ok = m_gnome_print_lib->IsLoaded();
94
95 if (m_ok)
96 InitializeMethods();
97 }
98
99 wxGnomePrintLibrary::~wxGnomePrintLibrary()
100 {
101 delete m_gnome_print_lib;
102 }
103
104 bool wxGnomePrintLibrary::IsOk()
105 {
106 return m_ok;
107 }
108
109 void wxGnomePrintLibrary::InitializeMethods()
110 {
111 m_ok = false;
112 bool success;
113
114 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_newpath, success )
115 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_moveto, success )
116 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_lineto, success )
117 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_curveto, success )
118 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_closepath, success )
119 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_stroke, success )
120 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_fill, success )
121 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_setrgbcolor, success )
122 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_setlinewidth, success )
123
124 m_ok = true;
125 }
126
127 static wxGnomePrintLibrary* gs_lgp = NULL;
128
129 //----------------------------------------------------------------------------
130 // wxGnomePrintNativeData
131 //----------------------------------------------------------------------------
132
133 IMPLEMENT_CLASS(wxGnomePrintNativeData, wxPrintNativeDataBase)
134
135 wxGnomePrintNativeData::wxGnomePrintNativeData()
136 {
137 m_config = gnome_print_config_default();
138 m_job = gnome_print_job_new( m_config );
139 }
140
141 wxGnomePrintNativeData::~wxGnomePrintNativeData()
142 {
143 g_object_unref (G_OBJECT (m_config));
144 }
145
146 bool wxGnomePrintNativeData::TransferTo( wxPrintData &data )
147 {
148 // TODO
149 return true;
150 }
151
152 bool wxGnomePrintNativeData::TransferFrom( const wxPrintData &data )
153 {
154 // TODO
155 return true;
156 }
157
158 //----------------------------------------------------------------------------
159 // wxGnomePrintFactory
160 //----------------------------------------------------------------------------
161
162 wxPrinterBase* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData *data )
163 {
164 return new wxGnomePrinter( data );
165 }
166
167 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
168 wxPrintout *printout,
169 wxPrintDialogData *data )
170 {
171 return new wxPostScriptPrintPreview( preview, printout, data );
172 }
173
174 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
175 wxPrintout *printout,
176 wxPrintData *data )
177 {
178 return new wxPostScriptPrintPreview( preview, printout, data );
179 }
180
181 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
182 wxPrintDialogData *data )
183 {
184 return new wxGnomePrintDialog( parent, data );
185 }
186
187 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
188 wxPrintData *data )
189 {
190 return new wxGnomePrintDialog( parent, data );
191 }
192
193 wxPageSetupDialogBase *wxGnomePrintFactory::CreatePageSetupDialog( wxWindow *parent,
194 wxPageSetupDialogData * data )
195 {
196 // The native page setup dialog is broken. It
197 // miscalculates newly entered values for the
198 // margins if you have not chose "points" but
199 // e.g. centimerters.
200 // This has been fixed in GNOME CVS (maybe
201 // fixed in libgnomeprintui 2.8.1)
202
203 return new wxGnomePageSetupDialog( parent, data );
204 }
205
206 bool wxGnomePrintFactory::HasPrintSetupDialog()
207 {
208 return false;
209 }
210
211 wxDialog *wxGnomePrintFactory::CreatePrintSetupDialog( wxWindow *parent, wxPrintData *data )
212 {
213 return NULL;
214 }
215
216 bool wxGnomePrintFactory::HasOwnPrintToFile()
217 {
218 return true;
219 }
220
221 bool wxGnomePrintFactory::HasPrinterLine()
222 {
223 return true;
224 }
225
226 wxString wxGnomePrintFactory::CreatePrinterLine()
227 {
228 // redundant now
229 return wxEmptyString;
230 }
231
232 bool wxGnomePrintFactory::HasStatusLine()
233 {
234 // redundant now
235 return true;
236 }
237
238 wxString wxGnomePrintFactory::CreateStatusLine()
239 {
240 // redundant now
241 return wxEmptyString;
242 }
243
244 wxPrintNativeDataBase *wxGnomePrintFactory::CreatePrintNativeData()
245 {
246 return new wxGnomePrintNativeData;
247 }
248
249 //----------------------------------------------------------------------------
250 // wxGnomePrintSetupDialog
251 //----------------------------------------------------------------------------
252
253 IMPLEMENT_CLASS(wxGnomePrintDialog, wxPrintDialogBase)
254
255 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow *parent, wxPrintDialogData *data )
256 : wxPrintDialogBase(parent, wxID_ANY, _("Print"),
257 wxPoint(0, 0), wxSize(600, 600),
258 wxDEFAULT_DIALOG_STYLE |
259 wxTAB_TRAVERSAL)
260 {
261 if (data)
262 m_printDialogData = *data;
263
264 Init();
265 }
266
267 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow *parent, wxPrintData *data )
268 : wxPrintDialogBase(parent, wxID_ANY, _("Print"),
269 wxPoint(0, 0), wxSize(600, 600),
270 wxDEFAULT_DIALOG_STYLE |
271 wxTAB_TRAVERSAL)
272 {
273 if (data)
274 m_printDialogData = *data;
275
276 Init();
277 }
278
279 void wxGnomePrintDialog::Init()
280 {
281 wxPrintData data = m_printDialogData.GetPrintData();
282
283 wxGnomePrintNativeData *native =
284 (wxGnomePrintNativeData*) data.GetNativeData();
285
286 m_widget = gnome_print_dialog_new( native->GetPrintJob(),
287 (guchar*)"Print",
288 GNOME_PRINT_DIALOG_RANGE|GNOME_PRINT_DIALOG_COPIES );
289
290 int flag = 0;
291 if (m_printDialogData.GetEnableSelection())
292 flag |= GNOME_PRINT_RANGE_SELECTION;
293 if (m_printDialogData.GetEnablePageNumbers())
294 flag |= GNOME_PRINT_RANGE_ALL|GNOME_PRINT_RANGE_RANGE;
295
296 gnome_print_dialog_construct_range_page( GNOME_PRINT_DIALOG( m_widget ),
297 flag,
298 m_printDialogData.GetMinPage(),
299 m_printDialogData.GetMaxPage(),
300 NULL,
301 NULL );
302 }
303
304 wxGnomePrintDialog::~wxGnomePrintDialog()
305 {
306 m_widget = NULL;
307 }
308
309 int wxGnomePrintDialog::ShowModal()
310 {
311 // Transfer data from m_printDalogData to dialog here
312
313 int response = gtk_dialog_run (GTK_DIALOG (m_widget));
314
315 if (response == GNOME_PRINT_DIALOG_RESPONSE_CANCEL)
316 {
317 gtk_widget_destroy(m_widget);
318 m_widget = NULL;
319
320 return wxID_CANCEL;
321 }
322
323 gint copies = 1;
324 gboolean collate = false;
325 gnome_print_dialog_get_copies( GNOME_PRINT_DIALOG(m_widget), &copies, &collate );
326 m_printDialogData.SetNoCopies( copies );
327 m_printDialogData.SetCollate( collate );
328
329 switch (gnome_print_dialog_get_range( GNOME_PRINT_DIALOG(m_widget) ))
330 {
331 case GNOME_PRINT_RANGE_SELECTION:
332 m_printDialogData.SetSelection( true );
333 break;
334 case GNOME_PRINT_RANGE_ALL:
335 m_printDialogData.SetAllPages( true );
336 m_printDialogData.SetFromPage( 0 );
337 m_printDialogData.SetToPage( 9999 );
338 break;
339 case GNOME_PRINT_RANGE_RANGE:
340 default:
341 gint start,end;
342 gnome_print_dialog_get_range_page( GNOME_PRINT_DIALOG(m_widget), &start, &end );
343 m_printDialogData.SetFromPage( start );
344 m_printDialogData.SetToPage( end );
345 break;
346 }
347
348 gtk_widget_destroy(m_widget);
349 m_widget = NULL;
350
351 if (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW)
352 return wxID_PREVIEW;
353
354 return wxID_OK;
355 }
356
357 wxDC *wxGnomePrintDialog::GetPrintDC()
358 {
359 // Later
360 return NULL;
361 }
362
363 bool wxGnomePrintDialog::Validate()
364 {
365 return true;
366 }
367
368 bool wxGnomePrintDialog::TransferDataToWindow()
369 {
370 return true;
371 }
372
373 bool wxGnomePrintDialog::TransferDataFromWindow()
374 {
375 return true;
376 }
377
378 //----------------------------------------------------------------------------
379 // wxGnomePageSetupDialog
380 //----------------------------------------------------------------------------
381
382 IMPLEMENT_CLASS(wxGnomePageSetupDialog, wxPageSetupDialogBase)
383
384 wxGnomePageSetupDialog::wxGnomePageSetupDialog( wxWindow *parent,
385 wxPageSetupDialogData* data )
386 {
387 if (data)
388 m_pageDialogData = *data;
389
390 wxGnomePrintNativeData *native =
391 (wxGnomePrintNativeData*) m_pageDialogData.GetPrintData().GetNativeData();
392
393 // This is required as the page setup dialog
394 // calculates wrong values otherwise.
395 gnome_print_config_set( native->GetPrintConfig(),
396 (const guchar*) GNOME_PRINT_KEY_PREFERED_UNIT,
397 (const guchar*) "Pts" );
398
399 m_widget = gtk_dialog_new();
400
401 gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( _("Page setup") ) );
402
403 GtkWidget *main = gnome_paper_selector_new_with_flags( native->GetPrintConfig(),
404 GNOME_PAPER_SELECTOR_MARGINS|GNOME_PAPER_SELECTOR_FEED_ORIENTATION );
405 gtk_container_set_border_width (GTK_CONTAINER (main), 8);
406 gtk_widget_show (main);
407
408 gtk_container_add( GTK_CONTAINER (GTK_DIALOG (m_widget)->vbox), main );
409
410 gtk_dialog_set_has_separator (GTK_DIALOG (m_widget), TRUE);
411
412 gtk_dialog_add_buttons (GTK_DIALOG (m_widget),
413 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
414 GTK_STOCK_OK, GTK_RESPONSE_OK,
415 NULL);
416
417 gtk_dialog_set_default_response (GTK_DIALOG (m_widget),
418 GTK_RESPONSE_OK);
419 }
420
421 wxGnomePageSetupDialog::~wxGnomePageSetupDialog()
422 {
423 }
424
425 wxPageSetupDialogData& wxGnomePageSetupDialog::GetPageSetupDialogData()
426 {
427 return m_pageDialogData;
428 }
429
430 int wxGnomePageSetupDialog::ShowModal()
431 {
432 wxGnomePrintNativeData *native =
433 (wxGnomePrintNativeData*) m_pageDialogData.GetPrintData().GetNativeData();
434 GnomePrintConfig *config = native->GetPrintConfig();
435
436 // Transfer data from m_pageDialogData to native dialog
437
438 int ret = gtk_dialog_run( GTK_DIALOG(m_widget) );
439
440 if (ret == GTK_RESPONSE_OK)
441 {
442 // Transfer data back to m_pageDialogData
443
444 // I don't know how querying the last parameter works
445 // I cannot test it as the dialog is currently broken
446 // anyways (it only works for points).
447 double ml,mr,mt,mb,pw,ph;
448 gnome_print_config_get_length (config,
449 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_LEFT, &ml, NULL);
450 gnome_print_config_get_length (config,
451 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT, &mr, NULL);
452 gnome_print_config_get_length (config,
453 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_TOP, &mt, NULL);
454 gnome_print_config_get_length (config,
455 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM, &mb, NULL);
456 gnome_print_config_get_length (config,
457 (const guchar*) GNOME_PRINT_KEY_PAPER_WIDTH, &pw, NULL);
458 gnome_print_config_get_length (config,
459 (const guchar*) GNOME_PRINT_KEY_PAPER_HEIGHT, &ph, NULL);
460
461 // This probably assumes that the user entered the
462 // values in Pts. Since that is the only the dialog
463 // works right now, we need to fix this later.
464 const GnomePrintUnit *mm_unit = gnome_print_unit_get_by_abbreviation( (const guchar*) "mm" );
465 const GnomePrintUnit *pts_unit = gnome_print_unit_get_by_abbreviation( (const guchar*) "Pts" );
466 gnome_print_convert_distance( &ml, pts_unit, mm_unit );
467 gnome_print_convert_distance( &mr, pts_unit, mm_unit );
468 gnome_print_convert_distance( &mt, pts_unit, mm_unit );
469 gnome_print_convert_distance( &mb, pts_unit, mm_unit );
470 gnome_print_convert_distance( &pw, pts_unit, mm_unit );
471 gnome_print_convert_distance( &ph, pts_unit, mm_unit );
472
473 m_pageDialogData.SetMarginTopLeft( wxPoint( (int)(ml+0.5), (int)(mt+0.5)) );
474 m_pageDialogData.SetMarginBottomRight( wxPoint( (int)(mr+0.5), (int)(mb+0.5)) );
475
476 m_pageDialogData.SetPaperSize( wxSize( (int)(pw+0.5), (int)(ph+0.5) ) );
477
478 #if 0
479 wxPrintf( wxT("paper %d %d, top margin %d\n"),
480 m_pageDialogData.GetPaperSize().x,
481 m_pageDialogData.GetPaperSize().y,
482 m_pageDialogData.GetMarginTopLeft().x );
483 #endif
484
485 ret = wxID_OK;
486 }
487 else
488 {
489 ret = wxID_CANCEL;
490 }
491
492 gtk_widget_destroy( m_widget );
493 m_widget = NULL;
494
495 return ret;
496 }
497
498 bool wxGnomePageSetupDialog::Validate()
499 {
500 return true;
501 }
502
503 bool wxGnomePageSetupDialog::TransferDataToWindow()
504 {
505 return true;
506 }
507
508 bool wxGnomePageSetupDialog::TransferDataFromWindow()
509 {
510 return true;
511 }
512
513 //----------------------------------------------------------------------------
514 // wxGnomePrinter
515 //----------------------------------------------------------------------------
516
517 IMPLEMENT_CLASS(wxGnomePrinter, wxPrinterBase)
518
519 wxGnomePrinter::wxGnomePrinter( wxPrintDialogData *data ) :
520 wxPrinterBase( data )
521 {
522 m_gpc = NULL;
523 m_native_preview = false;
524 }
525
526 wxGnomePrinter::~wxGnomePrinter()
527 {
528 }
529
530 bool wxGnomePrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt )
531 {
532 if (!printout)
533 {
534 sm_lastError = wxPRINTER_ERROR;
535 return false;
536 }
537
538 wxPrintData printdata = GetPrintDialogData().GetPrintData();
539 wxGnomePrintNativeData *native =
540 (wxGnomePrintNativeData*) printdata.GetNativeData();
541
542 GnomePrintJob *job = gnome_print_job_new( native->GetPrintConfig() );
543 m_gpc = gnome_print_job_get_context (job);
544
545 // The GnomePrintJob is temporarily stored in the
546 // native print data as the native print dialog
547 // needs to access it.
548 native->SetPrintJob( job );
549
550
551 printout->SetIsPreview(false);
552
553 if (m_printDialogData.GetMinPage() < 1)
554 m_printDialogData.SetMinPage(1);
555 if (m_printDialogData.GetMaxPage() < 1)
556 m_printDialogData.SetMaxPage(9999);
557
558 wxDC *dc;
559 if (prompt)
560 dc = PrintDialog( parent );
561 else
562 dc = new wxGnomePrintDC( this );
563
564 if (m_native_preview)
565 printout->SetIsPreview(true);
566
567 if (!dc)
568 {
569 gnome_print_job_close( job );
570 g_object_unref (G_OBJECT (job));
571 sm_lastError = wxPRINTER_ERROR;
572 return false;
573 }
574
575 wxSize ScreenPixels = wxGetDisplaySize();
576 wxSize ScreenMM = wxGetDisplaySizeMM();
577
578 printout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()),
579 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) );
580 printout->SetPPIPrinter( wxGnomePrintDC::GetResolution(),
581 wxGnomePrintDC::GetResolution() );
582
583 printout->SetDC(dc);
584
585 int w, h;
586 dc->GetSize(&w, &h);
587 printout->SetPageSizePixels((int)w, (int)h);
588 dc->GetSizeMM(&w, &h);
589 printout->SetPageSizeMM((int)w, (int)h);
590
591 printout->OnPreparePrinting();
592
593 // Get some parameters from the printout, if defined
594 int fromPage, toPage;
595 int minPage, maxPage;
596 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
597
598 if (maxPage == 0)
599 {
600 gnome_print_job_close( job );
601 g_object_unref (G_OBJECT (job));
602 sm_lastError = wxPRINTER_ERROR;
603 return false;
604 }
605
606 printout->OnBeginPrinting();
607
608 int minPageNum = minPage, maxPageNum = maxPage;
609
610 if ( !m_printDialogData.GetAllPages() )
611 {
612 minPageNum = m_printDialogData.GetFromPage();
613 maxPageNum = m_printDialogData.GetToPage();
614 }
615
616
617 int copyCount;
618 for ( copyCount = 1;
619 copyCount <= m_printDialogData.GetNoCopies();
620 copyCount++ )
621 {
622 if (!printout->OnBeginDocument(minPageNum, maxPageNum))
623 {
624 wxLogError(_("Could not start printing."));
625 sm_lastError = wxPRINTER_ERROR;
626 break;
627 }
628
629 int pn;
630 for ( pn = minPageNum;
631 pn <= maxPageNum && printout->HasPage(pn);
632 pn++ )
633 {
634 dc->StartPage();
635 printout->OnPrintPage(pn);
636 dc->EndPage();
637 }
638
639 printout->OnEndDocument();
640 printout->OnEndPrinting();
641 }
642
643 gnome_print_job_close( job );
644 if (m_native_preview)
645 {
646 wxString title( _("Print preview") );
647 gtk_widget_show( gnome_print_job_preview_new( job, (const guchar*)(const char*)wxGTK_CONV(title) ));
648 }
649 else
650 {
651 gnome_print_job_print( job );
652 }
653
654 g_object_unref (G_OBJECT (job));
655 delete dc;
656
657 return (sm_lastError == wxPRINTER_NO_ERROR);
658 }
659
660 wxDC* wxGnomePrinter::PrintDialog( wxWindow *parent )
661 {
662 wxGnomePrintDialog dialog( parent, &m_printDialogData );
663 int ret = dialog.ShowModal();
664 if (ret == wxID_CANCEL)
665 {
666 sm_lastError = wxPRINTER_ERROR;
667 return NULL;
668 }
669
670 m_native_preview = ret == wxID_PREVIEW;
671
672 m_printDialogData = dialog.GetPrintDialogData();
673 return new wxGnomePrintDC( this );
674 }
675
676 bool wxGnomePrinter::Setup( wxWindow *parent )
677 {
678 return false;
679 }
680
681 //-----------------------------------------------------------------------------
682 // wxGnomePrintDC
683 //-----------------------------------------------------------------------------
684
685 IMPLEMENT_CLASS(wxGnomePrintDC, wxDCBase)
686
687 wxGnomePrintDC::wxGnomePrintDC( wxGnomePrinter *printer )
688 {
689 m_printer = printer;
690
691 m_gpc = printer->GetPrintContext();
692
693 m_layout = gnome_print_pango_create_layout( m_gpc );
694 m_fontdesc = pango_font_description_from_string( "Sans 12" );
695
696 m_currentRed = 0;
697 m_currentBlue = 0;
698 m_currentGreen = 0;
699
700 m_signX = 1; // default x-axis left to right
701 m_signY = -1; // default y-axis bottom up -> top down
702 }
703
704 wxGnomePrintDC::~wxGnomePrintDC()
705 {
706 }
707
708 bool wxGnomePrintDC::Ok() const
709 {
710 return true;
711 }
712
713 bool wxGnomePrintDC::DoFloodFill(wxCoord x1, wxCoord y1, const wxColour &col, int style )
714 {
715 return false;
716 }
717
718 bool wxGnomePrintDC::DoGetPixel(wxCoord x1, wxCoord y1, wxColour *col) const
719 {
720 return false;
721 }
722
723 void wxGnomePrintDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
724 {
725 if (m_pen.GetStyle() == wxTRANSPARENT) return;
726
727 SetPen( m_pen );
728
729 gs_lgp->gnome_print_moveto ( m_gpc, XLOG2DEV(x1), YLOG2DEV(y1) );
730 gs_lgp->gnome_print_lineto ( m_gpc, XLOG2DEV(x2), YLOG2DEV(y2) );
731 gs_lgp->gnome_print_stroke ( m_gpc);
732
733 CalcBoundingBox( x1, y1 );
734 CalcBoundingBox( x2, y2 );
735 }
736
737 void wxGnomePrintDC::DoCrossHair(wxCoord x, wxCoord y)
738 {
739 }
740
741 void wxGnomePrintDC::DoDrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2,wxCoord xc,wxCoord yc)
742 {
743 }
744
745 void wxGnomePrintDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)
746 {
747 }
748
749 void wxGnomePrintDC::DoDrawPoint(wxCoord x, wxCoord y)
750 {
751 }
752
753 void wxGnomePrintDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset)
754 {
755 if (m_pen.GetStyle() == wxTRANSPARENT) return;
756
757 if (n <= 0) return;
758
759 SetPen (m_pen);
760
761 int i;
762 for ( i =0; i<n ; i++ )
763 CalcBoundingBox( XLOG2DEV(points[i].x+xoffset), YLOG2DEV(points[i].y+yoffset));
764
765 gs_lgp->gnome_print_moveto ( m_gpc, XLOG2DEV(points[0].x+xoffset), YLOG2DEV(points[0].y+yoffset) );
766
767 for (i = 1; i < n; i++)
768 gs_lgp->gnome_print_lineto ( m_gpc, XLOG2DEV(points[i].x+xoffset), YLOG2DEV(points[i].y+yoffset) );
769
770 gs_lgp->gnome_print_stroke ( m_gpc);
771 }
772
773 void wxGnomePrintDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
774 {
775 }
776
777 void wxGnomePrintDC::DoDrawPolyPolygon(int n, int count[], wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
778 {
779 }
780
781 void wxGnomePrintDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
782 {
783 if (m_brush.GetStyle () != wxTRANSPARENT)
784 {
785 SetBrush( m_brush );
786
787 gs_lgp->gnome_print_newpath( m_gpc );
788 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
789 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
790 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
791 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
792 gs_lgp->gnome_print_closepath( m_gpc );
793 gs_lgp->gnome_print_fill( m_gpc );
794
795 CalcBoundingBox( x, y );
796 CalcBoundingBox( x + width, y + height );
797 }
798
799 if (m_pen.GetStyle () != wxTRANSPARENT)
800 {
801 SetPen (m_pen);
802
803 gs_lgp->gnome_print_newpath( m_gpc );
804 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
805 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
806 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
807 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
808 gs_lgp->gnome_print_closepath( m_gpc );
809 gs_lgp->gnome_print_stroke( m_gpc );
810
811 CalcBoundingBox( x, y );
812 CalcBoundingBox( x + width, y + height );
813 }
814 }
815
816 void wxGnomePrintDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
817 {
818 }
819
820 void wxGnomePrintDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
821 {
822 if (m_brush.GetStyle () != wxTRANSPARENT)
823 {
824 SetBrush( m_brush );
825
826 gs_lgp->gnome_print_newpath( m_gpc );
827 gs_lgp->gnome_print_moveto( m_gpc,
828 XLOG2DEV(x), YLOG2DEV(y+height/2) );
829
830 // start with top half
831 gs_lgp->gnome_print_curveto( m_gpc,
832 XLOG2DEV(x), YLOG2DEV(y),
833 XLOG2DEV(x+width), YLOG2DEV(y),
834 XLOG2DEV(x+width), YLOG2DEV(y+height/2) );
835 // lower half
836 gs_lgp->gnome_print_curveto( m_gpc,
837 XLOG2DEV(x+width), YLOG2DEV(y+height),
838 XLOG2DEV(x), YLOG2DEV(y+height),
839 XLOG2DEV(x), YLOG2DEV(y+height/2) );
840
841 gs_lgp->gnome_print_closepath( m_gpc );
842 gs_lgp->gnome_print_fill( m_gpc );
843
844 CalcBoundingBox( x, y );
845 CalcBoundingBox( x + width, y + height );
846 }
847
848 if (m_pen.GetStyle () != wxTRANSPARENT)
849 {
850 SetPen (m_pen);
851
852 gs_lgp->gnome_print_newpath( m_gpc );
853 gs_lgp->gnome_print_moveto( m_gpc,
854 XLOG2DEV(x), YLOG2DEV(y+height/2) );
855
856 // start with top half
857 gs_lgp->gnome_print_curveto( m_gpc,
858 XLOG2DEV(x), YLOG2DEV(y),
859 XLOG2DEV(x+width), YLOG2DEV(y),
860 XLOG2DEV(x+width), YLOG2DEV(y+height/2) );
861 // lower half
862 gs_lgp->gnome_print_curveto( m_gpc,
863 XLOG2DEV(x+width), YLOG2DEV(y+height),
864 XLOG2DEV(x), YLOG2DEV(y+height),
865 XLOG2DEV(x), YLOG2DEV(y+height/2) );
866
867 gs_lgp->gnome_print_closepath( m_gpc );
868 gs_lgp->gnome_print_stroke( m_gpc );
869
870 CalcBoundingBox( x, y );
871 CalcBoundingBox( x + width, y + height );
872 }
873 }
874
875 void wxGnomePrintDC::DoDrawSpline(wxList *points)
876 {
877 }
878
879 bool wxGnomePrintDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
880 wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
881 wxCoord xsrcMask, wxCoord ysrcMask)
882 {
883 return false;
884 }
885
886 void wxGnomePrintDC::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
887 {
888 DoDrawBitmap( icon, x, y, true );
889 }
890
891 void wxGnomePrintDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool useMask )
892 {
893 if (!bitmap.Ok()) return;
894
895 if (bitmap.HasPixbuf())
896 {
897 GdkPixbuf *pixbuf = bitmap.GetPixbuf();
898 guchar *raw_image = gdk_pixbuf_get_pixels( pixbuf );
899 bool has_alpha = gdk_pixbuf_get_has_alpha( pixbuf );
900 int rowstride = gdk_pixbuf_get_rowstride( pixbuf );
901 int height = gdk_pixbuf_get_height( pixbuf );
902 int width = gdk_pixbuf_get_width( pixbuf );
903
904 gnome_print_gsave( m_gpc );
905 double matrix[6];
906 matrix[0] = XLOG2DEVREL(width);
907 matrix[1] = 0;
908 matrix[2] = 0;
909 matrix[3] = YLOG2DEVREL(height);
910 matrix[4] = XLOG2DEV(x);
911 matrix[5] = YLOG2DEV(y+height);
912 gnome_print_concat( m_gpc, matrix );
913 gs_lgp->gnome_print_moveto( m_gpc, 0, 0 );
914 if (has_alpha)
915 gnome_print_rgbaimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
916 else
917 gnome_print_rgbimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
918 gnome_print_grestore( m_gpc );
919 }
920 else
921 {
922 wxImage image = bitmap.ConvertToImage();
923
924 if (!image.Ok()) return;
925
926 gnome_print_gsave( m_gpc );
927 double matrix[6];
928 matrix[0] = XLOG2DEVREL(image.GetWidth());
929 matrix[1] = 0;
930 matrix[2] = 0;
931 matrix[3] = YLOG2DEVREL(image.GetHeight());
932 matrix[4] = XLOG2DEV(x);
933 matrix[5] = YLOG2DEV(y+image.GetHeight());
934 gnome_print_concat( m_gpc, matrix );
935 gs_lgp->gnome_print_moveto( m_gpc, 0, 0 );
936 gnome_print_rgbimage( m_gpc, (guchar*) image.GetData(), image.GetWidth(), image.GetHeight(), image.GetWidth()*3 );
937 gnome_print_grestore( m_gpc );
938 }
939 }
940
941 void wxGnomePrintDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y )
942 {
943 DoDrawRotatedText( text, x, y, 0.0 );
944 }
945
946 void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
947 {
948 x = XLOG2DEV(x);
949 y = YLOG2DEV(y);
950
951 bool underlined = m_font.Ok() && m_font.GetUnderlined();
952
953 #if wxUSE_UNICODE
954 const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
955 #else
956 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text );
957 if ( !wdata )
958 return;
959 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
960 #endif
961
962 size_t datalen = strlen((const char*)data);
963 pango_layout_set_text( m_layout, (const char*) data, datalen);
964
965 if (underlined)
966 {
967 PangoAttrList *attrs = pango_attr_list_new();
968 PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
969 a->start_index = 0;
970 a->end_index = datalen;
971 pango_attr_list_insert(attrs, a);
972 pango_layout_set_attributes(m_layout, attrs);
973 pango_attr_list_unref(attrs);
974 }
975
976 if (m_textForegroundColour.Ok())
977 {
978 unsigned char red = m_textForegroundColour.Red();
979 unsigned char blue = m_textForegroundColour.Blue();
980 unsigned char green = m_textForegroundColour.Green();
981
982 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
983 {
984 double redPS = (double)(red) / 255.0;
985 double bluePS = (double)(blue) / 255.0;
986 double greenPS = (double)(green) / 255.0;
987
988 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
989
990 m_currentRed = red;
991 m_currentBlue = blue;
992 m_currentGreen = green;
993 }
994 }
995
996 int w,h;
997
998 if (fabs(m_scaleY - 1.0) > 0.00001)
999 {
1000 // If there is a user or actually any scale applied to
1001 // the device context, scale the font.
1002
1003 // scale font description
1004 gint oldSize = pango_font_description_get_size( m_fontdesc );
1005 double size = oldSize;
1006 size = size * m_scaleY;
1007 pango_font_description_set_size( m_fontdesc, (gint)size );
1008
1009 // actually apply scaled font
1010 pango_layout_set_font_description( m_layout, m_fontdesc );
1011
1012 pango_layout_get_pixel_size( m_layout, &w, &h );
1013 #if 0
1014 if ( m_backgroundMode == wxSOLID )
1015 {
1016 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1017 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
1018 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1019 }
1020 #endif
1021 // Draw layout.
1022 gs_lgp->gnome_print_moveto (m_gpc, x, y);
1023 if (fabs(angle) > 0.00001)
1024 {
1025 gnome_print_gsave( m_gpc );
1026 gnome_print_rotate( m_gpc, angle );
1027 gnome_print_pango_layout( m_gpc, m_layout );
1028 gnome_print_grestore( m_gpc );
1029 }
1030 else
1031 {
1032 gnome_print_pango_layout( m_gpc, m_layout );
1033 }
1034
1035 // reset unscaled size
1036 pango_font_description_set_size( m_fontdesc, oldSize );
1037
1038 // actually apply unscaled font
1039 pango_layout_set_font_description( m_layout, m_fontdesc );
1040 }
1041 else
1042 {
1043 pango_layout_get_pixel_size( m_layout, &w, &h );
1044 #if 0
1045 if ( m_backgroundMode == wxSOLID )
1046 {
1047 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1048 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
1049 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1050 }
1051 #endif
1052 // Draw layout.
1053 gs_lgp->gnome_print_moveto (m_gpc, x, y);
1054 if (fabs(angle) > 0.00001)
1055 {
1056 gnome_print_gsave( m_gpc );
1057 gnome_print_rotate( m_gpc, angle );
1058 gnome_print_pango_layout( m_gpc, m_layout );
1059 gnome_print_grestore( m_gpc );
1060 }
1061 else
1062 {
1063 gnome_print_pango_layout( m_gpc, m_layout );
1064 }
1065 }
1066
1067 if (underlined)
1068 {
1069 // undo underline attributes setting:
1070 pango_layout_set_attributes(m_layout, NULL);
1071 }
1072
1073 CalcBoundingBox (x + w, y + h);
1074 }
1075
1076 void wxGnomePrintDC::Clear()
1077 {
1078 }
1079
1080 void wxGnomePrintDC::SetFont( const wxFont& font )
1081 {
1082 m_font = font;
1083
1084 if (m_font.Ok())
1085 {
1086 if (m_fontdesc)
1087 pango_font_description_free( m_fontdesc );
1088
1089 m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description );
1090
1091 pango_layout_set_font_description( m_layout, m_fontdesc );
1092 }
1093 }
1094
1095 void wxGnomePrintDC::SetPen( const wxPen& pen )
1096 {
1097 if (!pen.Ok()) return;
1098
1099 // TODO: support for pen styles other than solid (use gnome_print_setdash)
1100
1101 m_pen = pen;
1102
1103 gs_lgp->gnome_print_setlinewidth( m_gpc, XLOG2DEVREL( 1000 * m_pen.GetWidth() ) / 1000.0f );
1104
1105 static const double dotted[] = {2.0, 5.0};
1106 static const double short_dashed[] = {4.0, 4.0};
1107 static const double wxCoord_dashed[] = {4.0, 8.0};
1108 static const double dotted_dashed[] = {6.0, 6.0, 2.0, 6.0};
1109
1110 switch (m_pen.GetStyle())
1111 {
1112 case wxDOT: gnome_print_setdash( m_gpc, 2, dotted, 0 ); break;
1113 case wxSHORT_DASH: gnome_print_setdash( m_gpc, 2, short_dashed, 0 ); break;
1114 case wxLONG_DASH: gnome_print_setdash( m_gpc, 2, wxCoord_dashed, 0 ); break;
1115 case wxDOT_DASH: gnome_print_setdash( m_gpc, 4, dotted_dashed, 0 ); break;
1116 case wxSOLID:
1117 case wxTRANSPARENT:
1118 default: gnome_print_setdash( m_gpc, 0, NULL, 0 ); break;
1119 }
1120
1121
1122 unsigned char red = m_pen.GetColour().Red();
1123 unsigned char blue = m_pen.GetColour().Blue();
1124 unsigned char green = m_pen.GetColour().Green();
1125
1126 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1127 {
1128 double redPS = (double)(red) / 255.0;
1129 double bluePS = (double)(blue) / 255.0;
1130 double greenPS = (double)(green) / 255.0;
1131
1132 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1133
1134 m_currentRed = red;
1135 m_currentBlue = blue;
1136 m_currentGreen = green;
1137 }
1138 }
1139
1140 void wxGnomePrintDC::SetBrush( const wxBrush& brush )
1141 {
1142 if (!brush.Ok()) return;
1143
1144 m_brush = brush;
1145
1146 // Brush colour
1147 unsigned char red = m_brush.GetColour().Red();
1148 unsigned char blue = m_brush.GetColour().Blue();
1149 unsigned char green = m_brush.GetColour().Green();
1150
1151 if (!m_colour)
1152 {
1153 // Anything not white is black
1154 if (! (red == (unsigned char) 255 &&
1155 blue == (unsigned char) 255 &&
1156 green == (unsigned char) 255) )
1157 {
1158 red = (unsigned char) 0;
1159 green = (unsigned char) 0;
1160 blue = (unsigned char) 0;
1161 }
1162 // setgray here ?
1163 }
1164
1165 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1166 {
1167 double redPS = (double)(red) / 255.0;
1168 double bluePS = (double)(blue) / 255.0;
1169 double greenPS = (double)(green) / 255.0;
1170
1171 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1172
1173 m_currentRed = red;
1174 m_currentBlue = blue;
1175 m_currentGreen = green;
1176 }
1177 }
1178
1179 void wxGnomePrintDC::SetLogicalFunction( int function )
1180 {
1181 }
1182
1183 void wxGnomePrintDC::SetBackground( const wxBrush& brush )
1184 {
1185 }
1186
1187 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
1188 {
1189 }
1190
1191 void wxGnomePrintDC::DestroyClippingRegion()
1192 {
1193 }
1194
1195 bool wxGnomePrintDC::StartDoc(const wxString& message)
1196 {
1197 SetDeviceOrigin( 0,0 );
1198
1199 return true;
1200 }
1201
1202 void wxGnomePrintDC::EndDoc()
1203 {
1204 gnome_print_end_doc( m_gpc );
1205 }
1206
1207 void wxGnomePrintDC::StartPage()
1208 {
1209 gnome_print_beginpage( m_gpc, (const guchar*) "1" );
1210 }
1211
1212 void wxGnomePrintDC::EndPage()
1213 {
1214 gnome_print_showpage( m_gpc );
1215 }
1216
1217 wxCoord wxGnomePrintDC::GetCharHeight() const
1218 {
1219 pango_layout_set_text( m_layout, "H", 1 );
1220
1221 int w,h;
1222 pango_layout_get_pixel_size( m_layout, &w, &h );
1223
1224 return h;
1225 }
1226
1227 wxCoord wxGnomePrintDC::GetCharWidth() const
1228 {
1229 pango_layout_set_text( m_layout, "H", 1 );
1230
1231 int w,h;
1232 pango_layout_get_pixel_size( m_layout, &w, &h );
1233
1234 return w;
1235 }
1236
1237 void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxCoord *height,
1238 wxCoord *descent,
1239 wxCoord *externalLeading,
1240 wxFont *theFont ) const
1241 {
1242 if ( width )
1243 *width = 0;
1244 if ( height )
1245 *height = 0;
1246 if ( descent )
1247 *descent = 0;
1248 if ( externalLeading )
1249 *externalLeading = 0;
1250
1251 if (string.IsEmpty())
1252 {
1253 return;
1254 }
1255
1256 // Set new font description
1257 if (theFont)
1258 pango_layout_set_font_description( m_layout, theFont->GetNativeFontInfo()->description );
1259
1260 // Set layout's text
1261 #if wxUSE_UNICODE
1262 const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
1263 const char *dataUTF8 = (const char *)data;
1264 #else
1265 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string );
1266 if ( !wdata )
1267 {
1268 if (width) (*width) = 0;
1269 if (height) (*height) = 0;
1270 return;
1271 }
1272 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1273 const char *dataUTF8 = (const char *)data;
1274 #endif
1275
1276 if ( !dataUTF8 )
1277 {
1278 // hardly ideal, but what else can we do if conversion failed?
1279 return;
1280 }
1281
1282 pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
1283
1284 int w,h;
1285 pango_layout_get_pixel_size( m_layout, &w, &h );
1286
1287 if (width)
1288 *width = (wxCoord) w;
1289 if (height)
1290 *height = (wxCoord) h;
1291 if (descent)
1292 {
1293 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
1294 int baseline = pango_layout_iter_get_baseline(iter);
1295 pango_layout_iter_free(iter);
1296 *descent = h - PANGO_PIXELS(baseline);
1297 }
1298
1299 // Reset old font description
1300 if (theFont)
1301 pango_layout_set_font_description( m_layout, m_fontdesc );
1302 }
1303
1304 void wxGnomePrintDC::DoGetSize(int* width, int* height) const
1305 {
1306 wxGnomePrintNativeData *native =
1307 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1308
1309 // Query page size. This seems to omit the margins
1310 // right now, although it shouldn't
1311 double pw,ph;
1312 gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1313
1314 if (width)
1315 *width = (int) (pw + 0.5);
1316 if (height)
1317 *height = (int) (ph + 0.5);
1318 }
1319
1320 void wxGnomePrintDC::DoGetSizeMM(int *width, int *height) const
1321 {
1322 wxGnomePrintNativeData *native =
1323 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1324
1325 // This code assumes values in Pts.
1326
1327 double pw,ph;
1328 gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1329
1330 // Convert to mm.
1331
1332 const GnomePrintUnit *mm_unit = gnome_print_unit_get_by_abbreviation( (const guchar*) "mm" );
1333 const GnomePrintUnit *pts_unit = gnome_print_unit_get_by_abbreviation( (const guchar*) "Pts" );
1334 gnome_print_convert_distance( &pw, pts_unit, mm_unit );
1335 gnome_print_convert_distance( &ph, pts_unit, mm_unit );
1336
1337 if (width)
1338 *width = (int) (pw + 0.5);
1339 if (height)
1340 *height = (int) (ph + 0.5);
1341 }
1342
1343 wxSize wxGnomePrintDC::GetPPI() const
1344 {
1345 return wxSize(72,72);
1346 }
1347
1348 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
1349 {
1350 m_signX = (xLeftRight ? 1 : -1);
1351 m_signY = (yBottomUp ? 1 : -1);
1352
1353 ComputeScaleAndOrigin();
1354 }
1355
1356 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x, wxCoord y )
1357 {
1358 int h = 0;
1359 int w = 0;
1360 GetSize( &w, &h );
1361
1362 wxDC::SetDeviceOrigin( x, h-y );
1363 }
1364
1365 void wxGnomePrintDC::SetResolution(int ppi)
1366 {
1367 }
1368
1369 int wxGnomePrintDC::GetResolution()
1370 {
1371 return 72;
1372 }
1373
1374
1375 class wxGnomePrintModule: public wxModule
1376 {
1377 public:
1378 wxGnomePrintModule() {}
1379 bool OnInit();
1380 void OnExit();
1381
1382 private:
1383 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule)
1384 };
1385
1386 bool wxGnomePrintModule::OnInit()
1387 {
1388 gs_lgp = new wxGnomePrintLibrary;
1389 if (gs_lgp->IsOk())
1390 wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory );
1391 return true;
1392 }
1393
1394 void wxGnomePrintModule::OnExit()
1395 {
1396 delete gs_lgp;
1397 }
1398
1399 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule, wxModule)
1400
1401 #endif
1402 // wxUSE_LIBGNOMEPRINT