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