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