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
25 #include "wx/fontutil.h"
26 #include "wx/printdlg.h"
27 #include "wx/gtk/private.h"
29 #include <libgnomeprint/gnome-print.h>
30 #include <libgnomeprint/gnome-print-pango.h>
31 #include <libgnomeprintui/gnome-print-dialog.h>
33 //----------------------------------------------------------------------------
34 // wxGnomePrintNativeData
35 //----------------------------------------------------------------------------
37 IMPLEMENT_CLASS(wxGnomePrintNativeData
, wxPrintNativeDataBase
)
39 wxGnomePrintNativeData::wxGnomePrintNativeData()
41 m_config
= gnome_print_config_default();
42 m_job
= gnome_print_job_new( m_config
);
45 wxGnomePrintNativeData::~wxGnomePrintNativeData()
47 g_object_unref (G_OBJECT (m_config
));
48 g_object_unref (G_OBJECT (m_job
));
51 bool wxGnomePrintNativeData::TransferTo( wxPrintData
&data
)
57 bool wxGnomePrintNativeData::TransferFrom( const wxPrintData
&data
)
63 //----------------------------------------------------------------------------
64 // wxGnomePrintFactory
65 //----------------------------------------------------------------------------
67 wxPrinterBase
* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData
*data
)
69 return new wxGnomePrinter( data
);
72 wxPrintPreviewBase
*wxGnomePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
74 wxPrintDialogData
*data
)
76 return new wxPostScriptPrintPreview( preview
, printout
, data
);
79 wxPrintPreviewBase
*wxGnomePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
83 return new wxPostScriptPrintPreview( preview
, printout
, data
);
86 wxPrintDialogBase
*wxGnomePrintFactory::CreatePrintDialog( wxWindow
*parent
,
87 wxPrintDialogData
*data
)
89 return new wxGenericPrintDialog( parent
, data
);
92 wxPrintDialogBase
*wxGnomePrintFactory::CreatePrintDialog( wxWindow
*parent
,
95 return new wxGenericPrintDialog( parent
, data
);
98 bool wxGnomePrintFactory::HasPrintSetupDialog()
103 wxDialog
*wxGnomePrintFactory::CreatePrintSetupDialog( wxWindow
*parent
, wxPrintData
*data
)
105 return new wxGnomePrintSetupDialog( parent
, data
);
108 bool wxGnomePrintFactory::HasOwnPrintToFile()
113 bool wxGnomePrintFactory::HasPrinterLine()
118 wxString
wxGnomePrintFactory::CreatePrinterLine()
120 // We should query "gnome_config_default" here
121 return _("GNOME print");
124 bool wxGnomePrintFactory::HasStatusLine()
129 wxString
wxGnomePrintFactory::CreateStatusLine()
131 // We should query "gnome_config_default" here
135 wxPrintNativeDataBase
*wxGnomePrintFactory::CreatePrintNativeData()
137 return new wxGnomePrintNativeData
;
140 //----------------------------------------------------------------------------
141 // wxGnomePrintSetupDialog
142 //----------------------------------------------------------------------------
144 IMPLEMENT_CLASS(wxGnomePrintSetupDialog
, wxDialog
)
146 wxGnomePrintSetupDialog::wxGnomePrintSetupDialog( wxWindow
*parent
, wxPrintData
*data
)
148 wxGnomePrintNativeData
*native
=
149 (wxGnomePrintNativeData
*) data
->GetNativeData();
151 m_widget
= gnome_print_dialog_new (native
->GetPrintJob(), (guchar
*)"Print setup", 0);
154 wxGnomePrintSetupDialog::~wxGnomePrintSetupDialog()
159 int wxGnomePrintSetupDialog::ShowModal()
161 int response
= gtk_dialog_run (GTK_DIALOG (m_widget
));
162 gtk_widget_destroy(m_widget
);
165 if (response
== GNOME_PRINT_DIALOG_RESPONSE_CANCEL
)
171 bool wxGnomePrintSetupDialog::Validate()
176 bool wxGnomePrintSetupDialog::TransferDataToWindow()
181 bool wxGnomePrintSetupDialog::TransferDataFromWindow()
187 //----------------------------------------------------------------------------
189 //----------------------------------------------------------------------------
191 IMPLEMENT_CLASS(wxGnomePrinter
, wxPrinterBase
)
193 wxGnomePrinter::wxGnomePrinter( wxPrintDialogData
*data
) :
194 wxPrinterBase( data
)
199 wxGnomePrinter::~wxGnomePrinter()
203 bool wxGnomePrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
207 sm_lastError
= wxPRINTER_ERROR
;
211 wxPrintData printdata
= GetPrintDialogData().GetPrintData();
212 wxGnomePrintNativeData
*data
=
213 (wxGnomePrintNativeData
*) printdata
.GetNativeData();
215 // The GnomePrintJob is temporarily stored in the
216 // native print data as the native print setup dialog
217 // needs to access it.
218 GnomePrintJob
*job
= data
->GetPrintJob();
219 m_gpc
= gnome_print_job_get_context (job
);
221 printout
->SetIsPreview(false);
223 if (m_printDialogData
.GetMinPage() < 1)
224 m_printDialogData
.SetMinPage(1);
225 if (m_printDialogData
.GetMaxPage() < 1)
226 m_printDialogData
.SetMaxPage(9999);
230 dc
= PrintDialog( parent
);
232 dc
= new wxGnomePrintDC( this );
236 gnome_print_job_close( job
);
237 sm_lastError
= wxPRINTER_ERROR
;
241 wxSize ScreenPixels
= wxGetDisplaySize();
242 wxSize ScreenMM
= wxGetDisplaySizeMM();
244 printout
->SetPPIScreen( (int) ((ScreenPixels
.GetWidth() * 25.4) / ScreenMM
.GetWidth()),
245 (int) ((ScreenPixels
.GetHeight() * 25.4) / ScreenMM
.GetHeight()) );
246 printout
->SetPPIPrinter( wxPostScriptDC::GetResolution(),
247 wxPostScriptDC::GetResolution() );
253 printout
->SetPageSizePixels((int)w
, (int)h
);
254 dc
->GetSizeMM(&w
, &h
);
255 printout
->SetPageSizeMM((int)w
, (int)h
);
257 printout
->OnPreparePrinting();
258 printout
->OnBeginPrinting();
260 if (!printout
->OnBeginDocument(0, 0))
262 sm_lastError
= wxPRINTER_ERROR
;
267 for (pn
= 1; pn
<= 2; pn
++)
270 printout
->OnPrintPage(pn
);
274 printout
->OnEndDocument();
275 printout
->OnEndPrinting();
278 gnome_print_job_close( job
);
279 gnome_print_job_print( job
);
283 return (sm_lastError
== wxPRINTER_NO_ERROR
);
286 wxDC
* wxGnomePrinter::PrintDialog( wxWindow
*parent
)
288 wxPrintDialog
dialog( parent
, &m_printDialogData
);
289 if (dialog
.ShowModal() == wxID_CANCEL
)
291 sm_lastError
= wxPRINTER_ERROR
;
295 return new wxGnomePrintDC( this );
298 bool wxGnomePrinter::Setup( wxWindow
*parent
)
303 //-----------------------------------------------------------------------------
305 //-----------------------------------------------------------------------------
307 IMPLEMENT_CLASS(wxGnomePrintDC
, wxDCBase
)
309 wxGnomePrintDC::wxGnomePrintDC( wxGnomePrinter
*printer
)
313 m_gpc
= printer
->GetPrintContext();
315 m_layout
= gnome_print_pango_create_layout( m_gpc
);
316 m_fontdesc
= pango_font_description_from_string( "Sans 12" );
322 m_signX
= 1; // default x-axis left to right
323 m_signY
= -1; // default y-axis bottom up -> top down
326 wxGnomePrintDC::~wxGnomePrintDC()
330 bool wxGnomePrintDC::Ok() const
335 bool wxGnomePrintDC::DoFloodFill(wxCoord x1
, wxCoord y1
, const wxColour
&col
, int style
)
340 bool wxGnomePrintDC::DoGetPixel(wxCoord x1
, wxCoord y1
, wxColour
*col
) const
345 void wxGnomePrintDC::DoDrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
347 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
351 gnome_print_moveto ( m_gpc
, XDEV2LOG(x1
), YDEV2LOG(y1
) );
352 gnome_print_lineto ( m_gpc
, XDEV2LOG(x2
), YDEV2LOG(y2
) );
353 gnome_print_stroke ( m_gpc
);
355 CalcBoundingBox( x1
, y1
);
356 CalcBoundingBox( x2
, y2
);
359 void wxGnomePrintDC::DoCrossHair(wxCoord x
, wxCoord y
)
363 void wxGnomePrintDC::DoDrawArc(wxCoord x1
,wxCoord y1
,wxCoord x2
,wxCoord y2
,wxCoord xc
,wxCoord yc
)
367 void wxGnomePrintDC::DoDrawEllipticArc(wxCoord x
,wxCoord y
,wxCoord w
,wxCoord h
,double sa
,double ea
)
371 void wxGnomePrintDC::DoDrawPoint(wxCoord x
, wxCoord y
)
375 void wxGnomePrintDC::DoDrawLines(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
379 void wxGnomePrintDC::DoDrawPolygon(int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
383 void wxGnomePrintDC::DoDrawPolyPolygon(int n
, int count
[], wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
387 void wxGnomePrintDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
389 if (m_brush
.GetStyle () != wxTRANSPARENT
)
393 gnome_print_newpath( m_gpc
);
394 gnome_print_moveto( m_gpc
, XLOG2DEV(x
), YLOG2DEV(y
) );
395 gnome_print_lineto( m_gpc
, XLOG2DEV(x
+ width
), YLOG2DEV(y
) );
396 gnome_print_lineto( m_gpc
, XLOG2DEV(x
+ width
), YLOG2DEV(y
+ height
) );
397 gnome_print_lineto( m_gpc
, XLOG2DEV(x
), YLOG2DEV(y
+ height
) );
398 gnome_print_closepath( m_gpc
);
399 gnome_print_fill( m_gpc
);
401 CalcBoundingBox( x
, y
);
402 CalcBoundingBox( x
+ width
, y
+ height
);
405 if (m_pen
.GetStyle () != wxTRANSPARENT
)
409 gnome_print_newpath( m_gpc
);
410 gnome_print_moveto( m_gpc
, XLOG2DEV(x
), YLOG2DEV(y
) );
411 gnome_print_lineto( m_gpc
, XLOG2DEV(x
+ width
), YLOG2DEV(y
) );
412 gnome_print_lineto( m_gpc
, XLOG2DEV(x
+ width
), YLOG2DEV(y
+ height
) );
413 gnome_print_lineto( m_gpc
, XLOG2DEV(x
), YLOG2DEV(y
+ height
) );
414 gnome_print_closepath( m_gpc
);
415 gnome_print_stroke( m_gpc
);
417 CalcBoundingBox( x
, y
);
418 CalcBoundingBox( x
+ width
, y
+ height
);
422 void wxGnomePrintDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
426 void wxGnomePrintDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
430 void wxGnomePrintDC::DoDrawSpline(wxList
*points
)
434 bool wxGnomePrintDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
435 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int rop
, bool useMask
,
436 wxCoord xsrcMask
, wxCoord ysrcMask
)
441 void wxGnomePrintDC::DoDrawIcon( const wxIcon
& icon
, wxCoord x
, wxCoord y
)
445 void wxGnomePrintDC::DoDrawBitmap( const wxBitmap
& bitmap
, wxCoord x
, wxCoord y
, bool useMask
)
449 void wxGnomePrintDC::DoDrawText(const wxString
& text
, wxCoord x
, wxCoord y
)
451 if (m_textForegroundColour
.Ok())
453 unsigned char red
= m_textForegroundColour
.Red();
454 unsigned char blue
= m_textForegroundColour
.Blue();
455 unsigned char green
= m_textForegroundColour
.Green();
457 if (!(red
== m_currentRed
&& green
== m_currentGreen
&& blue
== m_currentBlue
))
459 double redPS
= (double)(red
) / 255.0;
460 double bluePS
= (double)(blue
) / 255.0;
461 double greenPS
= (double)(green
) / 255.0;
463 gnome_print_setrgbcolor( m_gpc
, redPS
, bluePS
, greenPS
);
466 m_currentBlue
= blue
;
467 m_currentGreen
= green
;
474 bool underlined
= m_font
.Ok() && m_font
.GetUnderlined();
477 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
479 const wxWCharBuffer wdata
= wxConvLocal
.cMB2WC( text
);
482 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( wdata
);
485 size_t datalen
= strlen((const char*)data
);
486 pango_layout_set_text( m_layout
, (const char*) data
, datalen
);
490 PangoAttrList
*attrs
= pango_attr_list_new();
491 PangoAttribute
*a
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
);
493 a
->end_index
= datalen
;
494 pango_attr_list_insert(attrs
, a
);
495 pango_layout_set_attributes(m_layout
, attrs
);
496 pango_attr_list_unref(attrs
);
499 gnome_print_moveto (m_gpc
, x
, y
);
500 gnome_print_pango_layout( m_gpc
, m_layout
);
504 // undo underline attributes setting:
505 pango_layout_set_attributes(m_layout
, NULL
);
508 // CalcBoundingBox (x + width, y + height);
509 CalcBoundingBox (x
, y
);
512 void wxGnomePrintDC::DoDrawRotatedText(const wxString
& text
, wxCoord x
, wxCoord y
, double angle
)
516 void wxGnomePrintDC::Clear()
520 void wxGnomePrintDC::SetFont( const wxFont
& font
)
527 pango_font_description_free( m_fontdesc
);
529 m_fontdesc
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description
);
531 pango_layout_set_font_description( m_layout
, m_fontdesc
);
535 void wxGnomePrintDC::SetPen( const wxPen
& pen
)
537 if (!pen
.Ok()) return;
539 int oldStyle
= m_pen
.GetStyle();
543 gnome_print_setlinewidth( m_gpc
, XLOG2DEVREL( 1000 * m_pen
.GetWidth() ) / 1000.0f
);
545 unsigned char red
= m_pen
.GetColour().Red();
546 unsigned char blue
= m_pen
.GetColour().Blue();
547 unsigned char green
= m_pen
.GetColour().Green();
549 if (!(red
== m_currentRed
&& green
== m_currentGreen
&& blue
== m_currentBlue
))
551 double redPS
= (double)(red
) / 255.0;
552 double bluePS
= (double)(blue
) / 255.0;
553 double greenPS
= (double)(green
) / 255.0;
555 gnome_print_setrgbcolor( m_gpc
, redPS
, bluePS
, greenPS
);
558 m_currentBlue
= blue
;
559 m_currentGreen
= green
;
563 void wxGnomePrintDC::SetBrush( const wxBrush
& brush
)
567 void wxGnomePrintDC::SetLogicalFunction( int function
)
571 void wxGnomePrintDC::SetBackground( const wxBrush
& brush
)
575 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
579 void wxGnomePrintDC::DestroyClippingRegion()
583 bool wxGnomePrintDC::StartDoc(const wxString
& message
)
585 SetDeviceOrigin( 0,0 );
590 void wxGnomePrintDC::EndDoc()
594 void wxGnomePrintDC::StartPage()
596 gnome_print_beginpage( m_gpc
, (const guchar
*) "1" );
599 void wxGnomePrintDC::EndPage()
601 gnome_print_showpage( m_gpc
);
604 wxCoord
wxGnomePrintDC::GetCharHeight() const
609 wxCoord
wxGnomePrintDC::GetCharWidth() const
614 void wxGnomePrintDC::DoGetTextExtent(const wxString
& string
, wxCoord
*width
, wxCoord
*height
,
616 wxCoord
*externalLeading
,
617 wxFont
*theFont
) const
625 if ( externalLeading
)
626 *externalLeading
= 0;
628 if (string
.IsEmpty())
633 // Set new font description
635 pango_layout_set_font_description( m_layout
, theFont
->GetNativeFontInfo()->description
);
639 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
640 const char *dataUTF8
= (const char *)data
;
642 const wxWCharBuffer wdata
= wxConvLocal
.cMB2WC( string
);
645 if (width
) (*width
) = 0;
646 if (height
) (*height
) = 0;
649 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( wdata
);
650 const char *dataUTF8
= (const char *)data
;
655 // hardly ideal, but what else can we do if conversion failed?
659 pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) );
662 pango_layout_get_pixel_size( m_layout
, &w
, &h
);
665 *width
= (wxCoord
) w
;
667 *height
= (wxCoord
) h
;
670 PangoLayoutIter
*iter
= pango_layout_get_iter(m_layout
);
671 int baseline
= pango_layout_iter_get_baseline(iter
);
672 pango_layout_iter_free(iter
);
673 *descent
= h
- PANGO_PIXELS(baseline
);
676 // Reset old font description
678 pango_layout_set_font_description( m_layout
, m_fontdesc
);
681 void wxGnomePrintDC::DoGetSize(int* width
, int* height
) const
683 // No idea if that is efficient
684 GnomePrintConfig
*config
= gnome_print_config_default();
687 bool result
= gnome_print_config_get_page_size( config
, &w
, &h
);
691 // Standard PS resolution DIN A4 size.
702 void wxGnomePrintDC::DoGetSizeMM(int *width
, int *height
) const
706 /// Later, for now DIN A4
716 wxSize
wxGnomePrintDC::GetPPI() const
718 return wxSize(72,72);
721 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
723 m_signX
= (xLeftRight
? 1 : -1);
724 m_signY
= (yBottomUp
? 1 : -1);
726 ComputeScaleAndOrigin();
729 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x
, wxCoord y
)
735 wxDC::SetDeviceOrigin( x
, h
-y
);
738 void wxGnomePrintDC::SetResolution(int ppi
)
742 int wxGnomePrintDC::GetResolution()
748 class wxGnomePrintModule
: public wxModule
751 wxGnomePrintModule() {}
752 bool OnInit() { wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory
); return true; }
756 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule
)
759 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule
, wxModule
)
762 // wxUSE_LIBGNOMEPRINT