1 /////////////////////////////////////////////////////////////////////////////
3 // Author: Robert Roebling
4 // Purpose: Implement GNOME printing support
6 // Copyright: Robert Roebling
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
11 #pragma implementation "gprint.h"
14 // For compilers that support precompilation, includes "wx/wx.h".
15 #include "wx/wxprec.h"
21 #include "wx/gtk/gnome/gprint.h"
23 #if wxUSE_LIBGNOMEPRINT
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"
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>
40 //----------------------------------------------------------------------------
41 // wxGnomePrintNativeData
42 //----------------------------------------------------------------------------
44 IMPLEMENT_CLASS(wxGnomePrintNativeData
, wxPrintNativeDataBase
)
46 wxGnomePrintNativeData::wxGnomePrintNativeData()
48 m_config
= gnome_print_config_default();
49 m_job
= gnome_print_job_new( m_config
);
52 wxGnomePrintNativeData::~wxGnomePrintNativeData()
54 g_object_unref (G_OBJECT (m_config
));
57 bool wxGnomePrintNativeData::TransferTo( wxPrintData
&data
)
63 bool wxGnomePrintNativeData::TransferFrom( const wxPrintData
&data
)
69 //----------------------------------------------------------------------------
70 // wxGnomePrintFactory
71 //----------------------------------------------------------------------------
73 wxPrinterBase
* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData
*data
)
75 return new wxGnomePrinter( data
);
78 wxPrintPreviewBase
*wxGnomePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
80 wxPrintDialogData
*data
)
82 return new wxPostScriptPrintPreview( preview
, printout
, data
);
85 wxPrintPreviewBase
*wxGnomePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
89 return new wxPostScriptPrintPreview( preview
, printout
, data
);
92 wxPrintDialogBase
*wxGnomePrintFactory::CreatePrintDialog( wxWindow
*parent
,
93 wxPrintDialogData
*data
)
95 return new wxGnomePrintDialog( parent
, data
);
98 wxPrintDialogBase
*wxGnomePrintFactory::CreatePrintDialog( wxWindow
*parent
,
101 return new wxGnomePrintDialog( parent
, data
);
104 wxPageSetupDialogBase
*wxGnomePrintFactory::CreatePageSetupDialog( wxWindow
*parent
,
105 wxPageSetupDialogData
* data
)
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
110 // e.g. centimerters.
111 // This has been fixed in GNOME CVS (maybe
112 // fixed in libgnomeprintui 2.8.1)
114 return new wxGnomePageSetupDialog( parent
, data
);
117 bool wxGnomePrintFactory::HasPrintSetupDialog()
122 wxDialog
*wxGnomePrintFactory::CreatePrintSetupDialog( wxWindow
*parent
, wxPrintData
*data
)
127 bool wxGnomePrintFactory::HasOwnPrintToFile()
132 bool wxGnomePrintFactory::HasPrinterLine()
137 wxString
wxGnomePrintFactory::CreatePrinterLine()
140 return wxEmptyString
;
143 bool wxGnomePrintFactory::HasStatusLine()
149 wxString
wxGnomePrintFactory::CreateStatusLine()
152 return wxEmptyString
;
155 wxPrintNativeDataBase
*wxGnomePrintFactory::CreatePrintNativeData()
157 return new wxGnomePrintNativeData
;
160 //----------------------------------------------------------------------------
161 // wxGnomePrintSetupDialog
162 //----------------------------------------------------------------------------
164 IMPLEMENT_CLASS(wxGnomePrintDialog
, wxPrintDialogBase
)
166 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow
*parent
, wxPrintDialogData
*data
)
167 : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"),
168 wxPoint(0, 0), wxSize(600, 600),
169 wxDEFAULT_DIALOG_STYLE
|
173 m_printDialogData
= *data
;
178 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow
*parent
, wxPrintData
*data
)
179 : wxPrintDialogBase(parent
, wxID_ANY
, _("Print"),
180 wxPoint(0, 0), wxSize(600, 600),
181 wxDEFAULT_DIALOG_STYLE
|
185 m_printDialogData
= *data
;
190 void wxGnomePrintDialog::Init()
192 wxPrintData data
= m_printDialogData
.GetPrintData();
194 wxGnomePrintNativeData
*native
=
195 (wxGnomePrintNativeData
*) data
.GetNativeData();
197 m_widget
= gnome_print_dialog_new( native
->GetPrintJob(),
199 GNOME_PRINT_DIALOG_RANGE
|GNOME_PRINT_DIALOG_COPIES
);
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
;
207 gnome_print_dialog_construct_range_page( GNOME_PRINT_DIALOG( m_widget
),
209 m_printDialogData
.GetMinPage(),
210 m_printDialogData
.GetMaxPage(),
215 wxGnomePrintDialog::~wxGnomePrintDialog()
220 int wxGnomePrintDialog::ShowModal()
222 // Transfer data from m_printDalogData to dialog here
224 int response
= gtk_dialog_run (GTK_DIALOG (m_widget
));
226 if (response
== GNOME_PRINT_DIALOG_RESPONSE_CANCEL
)
228 gtk_widget_destroy(m_widget
);
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
);
240 switch (gnome_print_dialog_get_range( GNOME_PRINT_DIALOG(m_widget
) ))
242 case GNOME_PRINT_RANGE_SELECTION
:
243 m_printDialogData
.SetSelection( true );
245 case GNOME_PRINT_RANGE_ALL
:
246 m_printDialogData
.SetAllPages( true );
247 m_printDialogData
.SetFromPage( 0 );
248 m_printDialogData
.SetToPage( 9999 );
250 case GNOME_PRINT_RANGE_RANGE
:
253 gnome_print_dialog_get_range_page( GNOME_PRINT_DIALOG(m_widget
), &start
, &end
);
254 m_printDialogData
.SetFromPage( start
);
255 m_printDialogData
.SetToPage( end
);
259 gtk_widget_destroy(m_widget
);
262 if (response
== GNOME_PRINT_DIALOG_RESPONSE_PREVIEW
)
268 wxDC
*wxGnomePrintDialog::GetPrintDC()
274 bool wxGnomePrintDialog::Validate()
279 bool wxGnomePrintDialog::TransferDataToWindow()
284 bool wxGnomePrintDialog::TransferDataFromWindow()
289 //----------------------------------------------------------------------------
290 // wxGnomePageSetupDialog
291 //----------------------------------------------------------------------------
293 IMPLEMENT_CLASS(wxGnomePageSetupDialog
, wxPageSetupDialogBase
)
295 wxGnomePageSetupDialog::wxGnomePageSetupDialog( wxWindow
*parent
,
296 wxPageSetupDialogData
* data
)
299 m_pageDialogData
= *data
;
301 wxGnomePrintNativeData
*native
=
302 (wxGnomePrintNativeData
*) m_pageDialogData
.GetPrintData().GetNativeData();
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" );
310 m_widget
= gtk_dialog_new();
312 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( _("Page setup") ) );
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
);
319 gtk_container_add( GTK_CONTAINER (GTK_DIALOG (m_widget
)->vbox
), main
);
321 gtk_dialog_set_has_separator (GTK_DIALOG (m_widget
), TRUE
);
323 gtk_dialog_add_buttons (GTK_DIALOG (m_widget
),
324 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
325 GTK_STOCK_OK
, GTK_RESPONSE_OK
,
328 gtk_dialog_set_default_response (GTK_DIALOG (m_widget
),
332 wxGnomePageSetupDialog::~wxGnomePageSetupDialog()
336 wxPageSetupDialogData
& wxGnomePageSetupDialog::GetPageSetupDialogData()
338 return m_pageDialogData
;
341 int wxGnomePageSetupDialog::ShowModal()
343 wxGnomePrintNativeData
*native
=
344 (wxGnomePrintNativeData
*) m_pageDialogData
.GetPrintData().GetNativeData();
345 GnomePrintConfig
*config
= native
->GetPrintConfig();
347 // Transfer data from m_pageDialogData to native dialog
349 int ret
= gtk_dialog_run( GTK_DIALOG(m_widget
) );
351 if (ret
== GTK_RESPONSE_OK
)
353 // Transfer data back to m_pageDialogData
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).
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
);
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
);
384 m_pageDialogData
.SetMarginTopLeft( wxPoint( (int)(ml
+0.5), (int)(mt
+0.5)) );
385 m_pageDialogData
.SetMarginBottomRight( wxPoint( (int)(mr
+0.5), (int)(mb
+0.5)) );
387 m_pageDialogData
.SetPaperSize( wxSize( (int)(pw
+0.5), (int)(ph
+0.5) ) );
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
);
403 gtk_widget_destroy( m_widget
);
409 bool wxGnomePageSetupDialog::Validate()
414 bool wxGnomePageSetupDialog::TransferDataToWindow()
419 bool wxGnomePageSetupDialog::TransferDataFromWindow()
424 //----------------------------------------------------------------------------
426 //----------------------------------------------------------------------------
428 IMPLEMENT_CLASS(wxGnomePrinter
, wxPrinterBase
)
430 wxGnomePrinter::wxGnomePrinter( wxPrintDialogData
*data
) :
431 wxPrinterBase( data
)
434 m_native_preview
= false;
437 wxGnomePrinter::~wxGnomePrinter()
441 bool wxGnomePrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
445 sm_lastError
= wxPRINTER_ERROR
;
449 wxPrintData printdata
= GetPrintDialogData().GetPrintData();
450 wxGnomePrintNativeData
*native
=
451 (wxGnomePrintNativeData
*) printdata
.GetNativeData();
453 GnomePrintJob
*job
= gnome_print_job_new( native
->GetPrintConfig() );
454 m_gpc
= gnome_print_job_get_context (job
);
456 // The GnomePrintJob is temporarily stored in the
457 // native print data as the native print dialog
458 // needs to access it.
459 native
->SetPrintJob( job
);
462 printout
->SetIsPreview(false);
464 if (m_printDialogData
.GetMinPage() < 1)
465 m_printDialogData
.SetMinPage(1);
466 if (m_printDialogData
.GetMaxPage() < 1)
467 m_printDialogData
.SetMaxPage(9999);
471 dc
= PrintDialog( parent
);
473 dc
= new wxGnomePrintDC( this );
475 if (m_native_preview
)
476 printout
->SetIsPreview(true);
480 gnome_print_job_close( job
);
481 g_object_unref (G_OBJECT (job
));
482 sm_lastError
= wxPRINTER_ERROR
;
486 wxSize ScreenPixels
= wxGetDisplaySize();
487 wxSize ScreenMM
= wxGetDisplaySizeMM();
489 printout
->SetPPIScreen( (int) ((ScreenPixels
.GetWidth() * 25.4) / ScreenMM
.GetWidth()),
490 (int) ((ScreenPixels
.GetHeight() * 25.4) / ScreenMM
.GetHeight()) );
491 printout
->SetPPIPrinter( wxGnomePrintDC::GetResolution(),
492 wxGnomePrintDC::GetResolution() );
498 printout
->SetPageSizePixels((int)w
, (int)h
);
499 dc
->GetSizeMM(&w
, &h
);
500 printout
->SetPageSizeMM((int)w
, (int)h
);
502 printout
->OnPreparePrinting();
504 // Get some parameters from the printout, if defined
505 int fromPage
, toPage
;
506 int minPage
, maxPage
;
507 printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
);
511 gnome_print_job_close( job
);
512 g_object_unref (G_OBJECT (job
));
513 sm_lastError
= wxPRINTER_ERROR
;
517 printout
->OnBeginPrinting();
519 int minPageNum
= minPage
, maxPageNum
= maxPage
;
521 if ( !m_printDialogData
.GetAllPages() )
523 minPageNum
= m_printDialogData
.GetFromPage();
524 maxPageNum
= m_printDialogData
.GetToPage();
530 copyCount
<= m_printDialogData
.GetNoCopies();
533 if (!printout
->OnBeginDocument(minPageNum
, maxPageNum
))
535 wxLogError(_("Could not start printing."));
536 sm_lastError
= wxPRINTER_ERROR
;
541 for ( pn
= minPageNum
;
542 pn
<= maxPageNum
&& printout
->HasPage(pn
);
546 printout
->OnPrintPage(pn
);
550 printout
->OnEndDocument();
551 printout
->OnEndPrinting();
554 gnome_print_job_close( job
);
555 if (m_native_preview
)
557 wxString
title( _("Print preview") );
558 gtk_widget_show( gnome_print_job_preview_new( job
, (const guchar
*)(const char*)wxGTK_CONV(title
) ));
562 gnome_print_job_print( job
);
565 g_object_unref (G_OBJECT (job
));
568 return (sm_lastError
== wxPRINTER_NO_ERROR
);
571 wxDC
* wxGnomePrinter::PrintDialog( wxWindow
*parent
)
573 wxGnomePrintDialog
dialog( parent
, &m_printDialogData
);
574 int ret
= dialog
.ShowModal();
575 if (ret
== wxID_CANCEL
)
577 sm_lastError
= wxPRINTER_ERROR
;
581 m_native_preview
= ret
== wxID_PREVIEW
;
583 m_printDialogData
= dialog
.GetPrintDialogData();
584 return new wxGnomePrintDC( this );
587 bool wxGnomePrinter::Setup( wxWindow
*parent
)
592 //-----------------------------------------------------------------------------
594 //-----------------------------------------------------------------------------
596 IMPLEMENT_CLASS(wxGnomePrintDC
, wxDCBase
)
598 wxGnomePrintDC::wxGnomePrintDC( wxGnomePrinter
*printer
)
602 m_gpc
= printer
->GetPrintContext();
604 m_layout
= gnome_print_pango_create_layout( m_gpc
);
605 m_fontdesc
= pango_font_description_from_string( "Sans 12" );
611 m_signX
= 1; // default x-axis left to right
612 m_signY
= -1; // default y-axis bottom up -> top down
615 wxGnomePrintDC::~wxGnomePrintDC()
619 bool wxGnomePrintDC::Ok() const
624 bool wxGnomePrintDC::DoFloodFill(wxCoord x1
, wxCoord y1
, const wxColour
&col
, int style
)
629 bool wxGnomePrintDC::DoGetPixel(wxCoord x1
, wxCoord y1
, wxColour
*col
) const
634 void wxGnomePrintDC::DoDrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
636 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
640 gnome_print_moveto ( m_gpc
, XLOG2DEV(x1
), YLOG2DEV(y1
) );
641 gnome_print_lineto ( m_gpc
, XLOG2DEV(x2
), YLOG2DEV(y2
) );
642 gnome_print_stroke ( m_gpc
);
644 CalcBoundingBox( x1
, y1
);
645 CalcBoundingBox( x2
, y2
);
648 void wxGnomePrintDC::DoCrossHair(wxCoord x
, wxCoord y
)
652 void wxGnomePrintDC::DoDrawArc(wxCoord x1
,wxCoord y1
,wxCoord x2
,wxCoord y2
,wxCoord xc
,wxCoord yc
)
656 void wxGnomePrintDC::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
)
660 void wxGnomePrintDC::DoDrawPoint(wxCoord x
, wxCoord y
)
664 void wxGnomePrintDC::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
666 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
673 for ( i
=0; i
<n
; i
++ )
674 CalcBoundingBox( XLOG2DEV(points
[i
].x
+xoffset
), YLOG2DEV(points
[i
].y
+yoffset
));
676 gnome_print_moveto ( m_gpc
, XLOG2DEV(points
[0].x
+xoffset
), YLOG2DEV(points
[0].y
+yoffset
) );
678 for (i
= 1; i
< n
; i
++)
679 gnome_print_lineto ( m_gpc
, XLOG2DEV(points
[i
].x
+xoffset
), YLOG2DEV(points
[i
].y
+yoffset
) );
681 gnome_print_stroke ( m_gpc
);
684 void wxGnomePrintDC::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
688 void wxGnomePrintDC::DoDrawPolyPolygon(int n
, int count
[], wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
692 void wxGnomePrintDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
694 if (m_brush
.GetStyle () != wxTRANSPARENT
)
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_fill( m_gpc
);
706 CalcBoundingBox( x
, y
);
707 CalcBoundingBox( x
+ width
, y
+ height
);
710 if (m_pen
.GetStyle () != wxTRANSPARENT
)
714 gnome_print_newpath( m_gpc
);
715 gnome_print_moveto( m_gpc
, XLOG2DEV(x
), YLOG2DEV(y
) );
716 gnome_print_lineto( m_gpc
, XLOG2DEV(x
+ width
), YLOG2DEV(y
) );
717 gnome_print_lineto( m_gpc
, XLOG2DEV(x
+ width
), YLOG2DEV(y
+ height
) );
718 gnome_print_lineto( m_gpc
, XLOG2DEV(x
), YLOG2DEV(y
+ height
) );
719 gnome_print_closepath( m_gpc
);
720 gnome_print_stroke( m_gpc
);
722 CalcBoundingBox( x
, y
);
723 CalcBoundingBox( x
+ width
, y
+ height
);
727 void wxGnomePrintDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
731 void wxGnomePrintDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
733 if (m_brush
.GetStyle () != wxTRANSPARENT
)
737 gnome_print_newpath( m_gpc
);
738 gnome_print_moveto( m_gpc
,
739 XLOG2DEV(x
), YLOG2DEV(y
+height
/2) );
741 // start with top half
742 gnome_print_curveto( m_gpc
,
743 XLOG2DEV(x
), YLOG2DEV(y
),
744 XLOG2DEV(x
+width
), YLOG2DEV(y
),
745 XLOG2DEV(x
+width
), YLOG2DEV(y
+height
/2) );
747 gnome_print_curveto( m_gpc
,
748 XLOG2DEV(x
+width
), YLOG2DEV(y
+height
),
749 XLOG2DEV(x
), YLOG2DEV(y
+height
),
750 XLOG2DEV(x
), YLOG2DEV(y
+height
/2) );
752 gnome_print_closepath( m_gpc
);
753 gnome_print_fill( m_gpc
);
755 CalcBoundingBox( x
, y
);
756 CalcBoundingBox( x
+ width
, y
+ height
);
759 if (m_pen
.GetStyle () != wxTRANSPARENT
)
763 gnome_print_newpath( m_gpc
);
764 gnome_print_moveto( m_gpc
,
765 XLOG2DEV(x
), YLOG2DEV(y
+height
/2) );
767 // start with top half
768 gnome_print_curveto( m_gpc
,
769 XLOG2DEV(x
), YLOG2DEV(y
),
770 XLOG2DEV(x
+width
), YLOG2DEV(y
),
771 XLOG2DEV(x
+width
), YLOG2DEV(y
+height
/2) );
773 gnome_print_curveto( m_gpc
,
774 XLOG2DEV(x
+width
), YLOG2DEV(y
+height
),
775 XLOG2DEV(x
), YLOG2DEV(y
+height
),
776 XLOG2DEV(x
), YLOG2DEV(y
+height
/2) );
778 gnome_print_closepath( m_gpc
);
779 gnome_print_stroke( m_gpc
);
781 CalcBoundingBox( x
, y
);
782 CalcBoundingBox( x
+ width
, y
+ height
);
786 void wxGnomePrintDC::DoDrawSpline(wxList
*points
)
790 bool wxGnomePrintDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
791 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int rop
, bool useMask
,
792 wxCoord xsrcMask
, wxCoord ysrcMask
)
797 void wxGnomePrintDC::DoDrawIcon( const wxIcon
& icon
, wxCoord x
, wxCoord y
)
799 DoDrawBitmap( icon
, x
, y
, true );
802 void wxGnomePrintDC::DoDrawBitmap( const wxBitmap
& bitmap
, wxCoord x
, wxCoord y
, bool useMask
)
804 if (!bitmap
.Ok()) return;
806 if (bitmap
.HasPixbuf())
808 GdkPixbuf
*pixbuf
= bitmap
.GetPixbuf();
809 guchar
*raw_image
= gdk_pixbuf_get_pixels( pixbuf
);
810 bool has_alpha
= gdk_pixbuf_get_has_alpha( pixbuf
);
811 int rowstride
= gdk_pixbuf_get_rowstride( pixbuf
);
812 int height
= gdk_pixbuf_get_height( pixbuf
);
813 int width
= gdk_pixbuf_get_width( pixbuf
);
815 gnome_print_gsave( m_gpc
);
817 matrix
[0] = XLOG2DEVREL(width
);
820 matrix
[3] = YLOG2DEVREL(height
);
821 matrix
[4] = XLOG2DEV(x
);
822 matrix
[5] = YLOG2DEV(y
+height
);
823 gnome_print_concat( m_gpc
, matrix
);
824 gnome_print_moveto( m_gpc
, 0, 0 );
826 gnome_print_rgbaimage( m_gpc
, (guchar
*)raw_image
, width
, height
, rowstride
);
828 gnome_print_rgbimage( m_gpc
, (guchar
*)raw_image
, width
, height
, rowstride
);
829 gnome_print_grestore( m_gpc
);
833 wxImage image
= bitmap
.ConvertToImage();
835 if (!image
.Ok()) return;
837 gnome_print_gsave( m_gpc
);
839 matrix
[0] = XLOG2DEVREL(image
.GetWidth());
842 matrix
[3] = YLOG2DEVREL(image
.GetHeight());
843 matrix
[4] = XLOG2DEV(x
);
844 matrix
[5] = YLOG2DEV(y
+image
.GetHeight());
845 gnome_print_concat( m_gpc
, matrix
);
846 gnome_print_moveto( m_gpc
, 0, 0 );
847 gnome_print_rgbimage( m_gpc
, (guchar
*) image
.GetData(), image
.GetWidth(), image
.GetHeight(), image
.GetWidth()*3 );
848 gnome_print_grestore( m_gpc
);
852 void wxGnomePrintDC::DoDrawText(const wxString
& text
, wxCoord x
, wxCoord y
)
854 DoDrawRotatedText( text
, x
, y
, 0.0 );
857 void wxGnomePrintDC::DoDrawRotatedText(const wxString
& text
, wxCoord x
, wxCoord y
, double angle
)
862 bool underlined
= m_font
.Ok() && m_font
.GetUnderlined();
865 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
867 const wxWCharBuffer wdata
= wxConvLocal
.cMB2WC( text
);
870 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( wdata
);
873 size_t datalen
= strlen((const char*)data
);
874 pango_layout_set_text( m_layout
, (const char*) data
, datalen
);
878 PangoAttrList
*attrs
= pango_attr_list_new();
879 PangoAttribute
*a
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
);
881 a
->end_index
= datalen
;
882 pango_attr_list_insert(attrs
, a
);
883 pango_layout_set_attributes(m_layout
, attrs
);
884 pango_attr_list_unref(attrs
);
887 if (m_textForegroundColour
.Ok())
889 unsigned char red
= m_textForegroundColour
.Red();
890 unsigned char blue
= m_textForegroundColour
.Blue();
891 unsigned char green
= m_textForegroundColour
.Green();
893 if (!(red
== m_currentRed
&& green
== m_currentGreen
&& blue
== m_currentBlue
))
895 double redPS
= (double)(red
) / 255.0;
896 double bluePS
= (double)(blue
) / 255.0;
897 double greenPS
= (double)(green
) / 255.0;
899 gnome_print_setrgbcolor( m_gpc
, redPS
, bluePS
, greenPS
);
902 m_currentBlue
= blue
;
903 m_currentGreen
= green
;
909 if (fabs(m_scaleY
- 1.0) > 0.00001)
911 // If there is a user or actually any scale applied to
912 // the device context, scale the font.
914 // scale font description
915 gint oldSize
= pango_font_description_get_size( m_fontdesc
);
916 double size
= oldSize
;
917 size
= size
* m_scaleY
;
918 pango_font_description_set_size( m_fontdesc
, (gint
)size
);
920 // actually apply scaled font
921 pango_layout_set_font_description( m_layout
, m_fontdesc
);
923 pango_layout_get_pixel_size( m_layout
, &w
, &h
);
925 if ( m_backgroundMode
== wxSOLID
)
927 gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor());
928 gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
);
929 gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor());
933 gnome_print_moveto (m_gpc
, x
, y
);
934 if (fabs(angle
) > 0.00001)
936 gnome_print_gsave( m_gpc
);
937 gnome_print_rotate( m_gpc
, angle
);
938 gnome_print_pango_layout( m_gpc
, m_layout
);
939 gnome_print_grestore( m_gpc
);
943 gnome_print_pango_layout( m_gpc
, m_layout
);
946 // reset unscaled size
947 pango_font_description_set_size( m_fontdesc
, oldSize
);
949 // actually apply unscaled font
950 pango_layout_set_font_description( m_layout
, m_fontdesc
);
954 pango_layout_get_pixel_size( m_layout
, &w
, &h
);
956 if ( m_backgroundMode
== wxSOLID
)
958 gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor());
959 gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
);
960 gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor());
964 gnome_print_moveto (m_gpc
, x
, y
);
965 if (fabs(angle
) > 0.00001)
967 gnome_print_gsave( m_gpc
);
968 gnome_print_rotate( m_gpc
, angle
);
969 gnome_print_pango_layout( m_gpc
, m_layout
);
970 gnome_print_grestore( m_gpc
);
974 gnome_print_pango_layout( m_gpc
, m_layout
);
980 // undo underline attributes setting:
981 pango_layout_set_attributes(m_layout
, NULL
);
984 CalcBoundingBox (x
+ w
, y
+ h
);
987 void wxGnomePrintDC::Clear()
991 void wxGnomePrintDC::SetFont( const wxFont
& font
)
998 pango_font_description_free( m_fontdesc
);
1000 m_fontdesc
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description
);
1002 pango_layout_set_font_description( m_layout
, m_fontdesc
);
1006 void wxGnomePrintDC::SetPen( const wxPen
& pen
)
1008 if (!pen
.Ok()) return;
1010 // TODO: support for pen styles other than solid (use gnome_print_setdash)
1014 gnome_print_setlinewidth( m_gpc
, XLOG2DEVREL( 1000 * m_pen
.GetWidth() ) / 1000.0f
);
1017 static const double dotted
[] = {2.0, 5.0};
1018 static const double short_dashed
[] = {4.0, 4.0};
1019 static const double wxCoord_dashed
[] = {4.0, 8.0};
1020 static const double dotted_dashed
[] = {6.0, 6.0, 2.0, 6.0};
1022 switch (m_pen
.GetStyle())
1024 case wxDOT
: gnome_print_setdash( m_gpc
, 2, dotted
, 0 ); break;
1025 case wxSHORT_DASH
: gnome_print_setdash( m_gpc
, 2, short_dashed
, 0 ); break;
1026 case wxLONG_DASH
: gnome_print_setdash( m_gpc
, 2, wxCoord_dashed
, 0 ); break;
1027 case wxDOT_DASH
: gnome_print_setdash( m_gpc
, 4, dotted_dashed
, 0 ); break;
1030 default: gnome_print_setdash( m_gpc
, 0, NULL
, 0 ); break;
1034 unsigned char red
= m_pen
.GetColour().Red();
1035 unsigned char blue
= m_pen
.GetColour().Blue();
1036 unsigned char green
= m_pen
.GetColour().Green();
1038 if (!(red
== m_currentRed
&& green
== m_currentGreen
&& blue
== m_currentBlue
))
1040 double redPS
= (double)(red
) / 255.0;
1041 double bluePS
= (double)(blue
) / 255.0;
1042 double greenPS
= (double)(green
) / 255.0;
1044 gnome_print_setrgbcolor( m_gpc
, redPS
, bluePS
, greenPS
);
1047 m_currentBlue
= blue
;
1048 m_currentGreen
= green
;
1052 void wxGnomePrintDC::SetBrush( const wxBrush
& brush
)
1054 if (!brush
.Ok()) return;
1059 unsigned char red
= m_brush
.GetColour().Red();
1060 unsigned char blue
= m_brush
.GetColour().Blue();
1061 unsigned char green
= m_brush
.GetColour().Green();
1065 // Anything not white is black
1066 if (! (red
== (unsigned char) 255 &&
1067 blue
== (unsigned char) 255 &&
1068 green
== (unsigned char) 255) )
1070 red
= (unsigned char) 0;
1071 green
= (unsigned char) 0;
1072 blue
= (unsigned char) 0;
1077 if (!(red
== m_currentRed
&& green
== m_currentGreen
&& blue
== m_currentBlue
))
1079 double redPS
= (double)(red
) / 255.0;
1080 double bluePS
= (double)(blue
) / 255.0;
1081 double greenPS
= (double)(green
) / 255.0;
1083 gnome_print_setrgbcolor( m_gpc
, redPS
, bluePS
, greenPS
);
1086 m_currentBlue
= blue
;
1087 m_currentGreen
= green
;
1091 void wxGnomePrintDC::SetLogicalFunction( int function
)
1095 void wxGnomePrintDC::SetBackground( const wxBrush
& brush
)
1099 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1103 void wxGnomePrintDC::DestroyClippingRegion()
1107 bool wxGnomePrintDC::StartDoc(const wxString
& message
)
1109 SetDeviceOrigin( 0,0 );
1114 void wxGnomePrintDC::EndDoc()
1116 gnome_print_end_doc( m_gpc
);
1119 void wxGnomePrintDC::StartPage()
1121 gnome_print_beginpage( m_gpc
, (const guchar
*) "1" );
1124 void wxGnomePrintDC::EndPage()
1126 gnome_print_showpage( m_gpc
);
1129 wxCoord
wxGnomePrintDC::GetCharHeight() const
1131 pango_layout_set_text( m_layout
, "H", 1 );
1134 pango_layout_get_pixel_size( m_layout
, &w
, &h
);
1139 wxCoord
wxGnomePrintDC::GetCharWidth() const
1141 pango_layout_set_text( m_layout
, "H", 1 );
1144 pango_layout_get_pixel_size( m_layout
, &w
, &h
);
1149 void wxGnomePrintDC::DoGetTextExtent(const wxString
& string
, wxCoord
*width
, wxCoord
*height
,
1151 wxCoord
*externalLeading
,
1152 wxFont
*theFont
) const
1160 if ( externalLeading
)
1161 *externalLeading
= 0;
1163 if (string
.IsEmpty())
1168 // Set new font description
1170 pango_layout_set_font_description( m_layout
, theFont
->GetNativeFontInfo()->description
);
1172 // Set layout's text
1174 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1175 const char *dataUTF8
= (const char *)data
;
1177 const wxWCharBuffer wdata
= wxConvLocal
.cMB2WC( string
);
1180 if (width
) (*width
) = 0;
1181 if (height
) (*height
) = 0;
1184 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( wdata
);
1185 const char *dataUTF8
= (const char *)data
;
1190 // hardly ideal, but what else can we do if conversion failed?
1194 pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) );
1197 pango_layout_get_pixel_size( m_layout
, &w
, &h
);
1200 *width
= (wxCoord
) w
;
1202 *height
= (wxCoord
) h
;
1205 PangoLayoutIter
*iter
= pango_layout_get_iter(m_layout
);
1206 int baseline
= pango_layout_iter_get_baseline(iter
);
1207 pango_layout_iter_free(iter
);
1208 *descent
= h
- PANGO_PIXELS(baseline
);
1211 // Reset old font description
1213 pango_layout_set_font_description( m_layout
, m_fontdesc
);
1216 void wxGnomePrintDC::DoGetSize(int* width
, int* height
) const
1218 wxGnomePrintNativeData
*native
=
1219 (wxGnomePrintNativeData
*) m_printData
.GetNativeData();
1221 // Query page size. This seems to omit the margins
1222 // right now, although it shouldn't
1224 gnome_print_job_get_page_size( native
->GetPrintJob(), &pw
, &ph
);
1227 *width
= (int) (pw
+ 0.5);
1229 *height
= (int) (ph
+ 0.5);
1232 void wxGnomePrintDC::DoGetSizeMM(int *width
, int *height
) const
1234 wxGnomePrintNativeData
*native
=
1235 (wxGnomePrintNativeData
*) m_printData
.GetNativeData();
1237 // This code assumes values in Pts.
1240 gnome_print_job_get_page_size( native
->GetPrintJob(), &pw
, &ph
);
1244 const GnomePrintUnit
*mm_unit
= gnome_print_unit_get_by_abbreviation( (const guchar
*) "mm" );
1245 const GnomePrintUnit
*pts_unit
= gnome_print_unit_get_by_abbreviation( (const guchar
*) "Pts" );
1246 gnome_print_convert_distance( &pw
, pts_unit
, mm_unit
);
1247 gnome_print_convert_distance( &ph
, pts_unit
, mm_unit
);
1250 *width
= (int) (pw
+ 0.5);
1252 *height
= (int) (ph
+ 0.5);
1255 wxSize
wxGnomePrintDC::GetPPI() const
1257 return wxSize(72,72);
1260 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
1262 m_signX
= (xLeftRight
? 1 : -1);
1263 m_signY
= (yBottomUp
? 1 : -1);
1265 ComputeScaleAndOrigin();
1268 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x
, wxCoord y
)
1274 wxDC::SetDeviceOrigin( x
, h
-y
);
1277 void wxGnomePrintDC::SetResolution(int ppi
)
1281 int wxGnomePrintDC::GetResolution()
1287 class wxGnomePrintModule
: public wxModule
1290 wxGnomePrintModule() {}
1291 bool OnInit() { wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory
); return true; }
1295 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule
)
1298 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule
, wxModule
)
1301 // wxUSE_LIBGNOMEPRINT