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