]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/gnome/gprint.cpp
Added spline support to GNOME print
[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 "wx/math.h"
26 #include "wx/fontutil.h"
27 #include "wx/printdlg.h"
28 #include "wx/gtk/private.h"
29 #include "wx/module.h"
30 #include "wx/generic/prntdlgg.h"
31 #include "wx/dynlib.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 #include "wx/html/forcelnk.h"
42 FORCE_LINK_ME(gnome_print)
43
44 //----------------------------------------------------------------------------
45 // wxGnomePrintLibrary
46 //----------------------------------------------------------------------------
47
48 #define wxDL_METHOD_DEFINE( rettype, name, args, shortargs, defret ) \
49 typedef rettype (* name ## Type) args ; \
50 name ## Type pfn_ ## name; \
51 rettype name args \
52 { if (m_ok) return pfn_ ## name shortargs ; return defret; }
53
54 #define wxDL_METHOD_LOAD( lib, name, success ) \
55 pfn_ ## name = (name ## Type) lib->GetSymbol( wxT(#name), &success ); \
56 if (!success) return;
57
58 class wxGnomePrintLibrary
59 {
60 public:
61 wxGnomePrintLibrary();
62 ~wxGnomePrintLibrary();
63
64 bool IsOk();
65 void InitializeMethods();
66
67 private:
68 bool m_ok;
69 wxDynamicLibrary *m_gnome_print_lib;
70 wxDynamicLibrary *m_gnome_printui_lib;
71
72 public:
73 wxDL_METHOD_DEFINE( gint, gnome_print_newpath,
74 (GnomePrintContext *pc), (pc), 0 )
75 wxDL_METHOD_DEFINE( gint, gnome_print_moveto,
76 (GnomePrintContext *pc, gdouble x, gdouble y), (pc, x, y), 0 )
77 wxDL_METHOD_DEFINE( gint, gnome_print_lineto,
78 (GnomePrintContext *pc, gdouble x, gdouble y), (pc, x, y), 0 )
79 wxDL_METHOD_DEFINE( gint, gnome_print_arcto,
80 (GnomePrintContext *pc, gdouble x, gdouble y, gdouble radius, gdouble angle1, gdouble angle2, gint direction ), (pc, x, y, radius, angle1, angle2, direction), 0 )
81 wxDL_METHOD_DEFINE( gint, gnome_print_curveto,
82 (GnomePrintContext *pc, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble x3, gdouble y3), (pc, x1, y1, x2, y2, x3, y3), 0 )
83 wxDL_METHOD_DEFINE( gint, gnome_print_closepath,
84 (GnomePrintContext *pc), (pc), 0 )
85 wxDL_METHOD_DEFINE( gint, gnome_print_stroke,
86 (GnomePrintContext *pc), (pc), 0 )
87 wxDL_METHOD_DEFINE( gint, gnome_print_fill,
88 (GnomePrintContext *pc), (pc), 0 )
89 wxDL_METHOD_DEFINE( gint, gnome_print_setrgbcolor,
90 (GnomePrintContext *pc, gdouble r, gdouble g, gdouble b), (pc, r, g, b), 0 )
91 wxDL_METHOD_DEFINE( gint, gnome_print_setlinewidth,
92 (GnomePrintContext *pc, gdouble width), (pc, width), 0 )
93 wxDL_METHOD_DEFINE( gint, gnome_print_setdash,
94 (GnomePrintContext *pc, gint n_values, const gdouble *values, gdouble offset), (pc, n_values, values, offset), 0 )
95
96 wxDL_METHOD_DEFINE( gint, gnome_print_rgbimage,
97 (GnomePrintContext *pc, const guchar *data, gint width, gint height, gint rowstride), (pc, data, width, height, rowstride ), 0 )
98 wxDL_METHOD_DEFINE( gint, gnome_print_rgbaimage,
99 (GnomePrintContext *pc, const guchar *data, gint width, gint height, gint rowstride), (pc, data, width, height, rowstride ), 0 )
100
101 wxDL_METHOD_DEFINE( gint, gnome_print_concat,
102 (GnomePrintContext *pc, const gdouble *matrix), (pc, matrix), 0 )
103 wxDL_METHOD_DEFINE( gint, gnome_print_scale,
104 (GnomePrintContext *pc, gdouble sx, gdouble sy), (pc, sx, sy), 0 )
105 wxDL_METHOD_DEFINE( gint, gnome_print_rotate,
106 (GnomePrintContext *pc, gdouble theta), (pc, theta), 0 )
107 wxDL_METHOD_DEFINE( gint, gnome_print_translate,
108 (GnomePrintContext *pc, gdouble x, gdouble y), (pc, x, y), 0 )
109
110 wxDL_METHOD_DEFINE( gint, gnome_print_gsave,
111 (GnomePrintContext *pc), (pc), 0 )
112 wxDL_METHOD_DEFINE( gint, gnome_print_grestore,
113 (GnomePrintContext *pc), (pc), 0 )
114
115 wxDL_METHOD_DEFINE( gint, gnome_print_beginpage,
116 (GnomePrintContext *pc, const guchar* name), (pc, name), 0 )
117 wxDL_METHOD_DEFINE( gint, gnome_print_showpage,
118 (GnomePrintContext *pc), (pc), 0 )
119 wxDL_METHOD_DEFINE( gint, gnome_print_end_doc,
120 (GnomePrintContext *pc), (pc), 0 )
121
122 wxDL_METHOD_DEFINE( PangoLayout*, gnome_print_pango_create_layout,
123 (GnomePrintContext *gpc), (gpc), NULL )
124 wxDL_METHOD_DEFINE( void, gnome_print_pango_layout,
125 (GnomePrintContext *gpc, PangoLayout *layout), (gpc, layout), /**/ )
126
127 wxDL_METHOD_DEFINE( GnomePrintJob*, gnome_print_job_new,
128 (GnomePrintConfig *config), (config), NULL )
129 wxDL_METHOD_DEFINE( GnomePrintContext*, gnome_print_job_get_context,
130 (GnomePrintJob *job), (job), NULL )
131 wxDL_METHOD_DEFINE( gint, gnome_print_job_close,
132 (GnomePrintJob *job), (job), 0 )
133 wxDL_METHOD_DEFINE( gint, gnome_print_job_print,
134 (GnomePrintJob *job), (job), 0 )
135 wxDL_METHOD_DEFINE( gboolean, gnome_print_job_get_page_size,
136 (GnomePrintJob *job, gdouble *width, gdouble *height), (job, width, height), 0 )
137
138 wxDL_METHOD_DEFINE( GnomePrintUnit*, gnome_print_unit_get_by_abbreviation,
139 (const guchar *abbreviation), (abbreviation), NULL )
140 wxDL_METHOD_DEFINE( gboolean, gnome_print_convert_distance,
141 (gdouble *distance, const GnomePrintUnit *from, const GnomePrintUnit *to), (distance, from, to), false )
142
143 wxDL_METHOD_DEFINE( GnomePrintConfig*, gnome_print_config_default,
144 (void), (), NULL )
145 wxDL_METHOD_DEFINE( gboolean, gnome_print_config_set,
146 (GnomePrintConfig *config, const guchar *key, const guchar *value), (config, key, value), false )
147 wxDL_METHOD_DEFINE( gboolean, gnome_print_config_get_length,
148 (GnomePrintConfig *config, const guchar *key, gdouble *val, const GnomePrintUnit **unit), (config, key, val, unit), false )
149
150 wxDL_METHOD_DEFINE( GtkWidget*, gnome_print_dialog_new,
151 (GnomePrintJob *gpj, const guchar *title, gint flags), (gpj, title, flags), NULL )
152 wxDL_METHOD_DEFINE( void, gnome_print_dialog_construct_range_page,
153 (GnomePrintDialog *gpd, gint flags, gint start, gint end,
154 const guchar *currentlabel, const guchar *rangelabel),
155 (gpd, flags, start, end, currentlabel, rangelabel), /**/ )
156 wxDL_METHOD_DEFINE( void, gnome_print_dialog_get_copies,
157 (GnomePrintDialog *gpd, gint *copies, gboolean *collate), (gpd, copies, collate), /**/ )
158 wxDL_METHOD_DEFINE( void, gnome_print_dialog_set_copies,
159 (GnomePrintDialog *gpd, gint copies, gint collate), (gpd, copies, collate), /**/ )
160 wxDL_METHOD_DEFINE( GnomePrintRangeType, gnome_print_dialog_get_range,
161 (GnomePrintDialog *gpd), (gpd), GNOME_PRINT_RANGETYPE_NONE )
162 wxDL_METHOD_DEFINE( int, gnome_print_dialog_get_range_page,
163 (GnomePrintDialog *gpd, gint *start, gint *end), (gpd, start, end), 0 )
164
165 wxDL_METHOD_DEFINE( GtkWidget*, gnome_paper_selector_new_with_flags,
166 (GnomePrintConfig *config, gint flags), (config, flags), NULL )
167
168 wxDL_METHOD_DEFINE( GtkWidget*, gnome_print_job_preview_new,
169 (GnomePrintJob *gpm, const guchar *title), (gpm, title), NULL )
170 };
171
172 wxGnomePrintLibrary::wxGnomePrintLibrary()
173 {
174 m_gnome_print_lib = NULL;
175 m_gnome_printui_lib = NULL;
176
177 wxLogNull log;
178
179 m_gnome_print_lib = new wxDynamicLibrary( wxT("libgnomeprint-2-2.so.0") );
180 m_ok = m_gnome_print_lib->IsLoaded();
181 if (!m_ok) return;
182
183 m_gnome_printui_lib = new wxDynamicLibrary( wxT("libgnomeprintui-2-2.so.0") );
184 m_ok = m_gnome_printui_lib->IsLoaded();
185 if (!m_ok) return;
186
187 InitializeMethods();
188 }
189
190 wxGnomePrintLibrary::~wxGnomePrintLibrary()
191 {
192 if (m_gnome_print_lib)
193 delete m_gnome_print_lib;
194 if (m_gnome_printui_lib)
195 delete m_gnome_printui_lib;
196 }
197
198 bool wxGnomePrintLibrary::IsOk()
199 {
200 return m_ok;
201 }
202
203 void wxGnomePrintLibrary::InitializeMethods()
204 {
205 m_ok = false;
206 bool success;
207
208 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_newpath, success )
209 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_moveto, success )
210 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_lineto, success )
211 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_curveto, success )
212 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_arcto, success )
213 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_closepath, success )
214 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_stroke, success )
215 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_fill, success )
216 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_setrgbcolor, success )
217 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_setlinewidth, success )
218 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_setdash, success )
219
220 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_rgbimage, success )
221 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_rgbaimage, success )
222
223 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_concat, success )
224 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_scale, success )
225 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_rotate, success )
226 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_translate, success )
227
228 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_gsave, success )
229 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_grestore, success )
230
231 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_beginpage, success )
232 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_showpage, success )
233 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_end_doc, success )
234
235 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_pango_create_layout, success )
236 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_pango_layout, success )
237
238 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_job_new, success )
239 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_job_get_context, success )
240 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_job_close, success )
241 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_job_print, success )
242 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_job_get_page_size, success )
243
244 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_unit_get_by_abbreviation, success )
245 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_convert_distance, success )
246
247 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_config_default, success )
248 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_config_set, success )
249 wxDL_METHOD_LOAD( m_gnome_print_lib, gnome_print_config_get_length, success )
250
251 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_dialog_new, success )
252 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_dialog_construct_range_page, success )
253 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_dialog_get_copies, success )
254 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_dialog_set_copies, success )
255 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_dialog_get_range, success )
256 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_dialog_get_range_page, success )
257
258 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_paper_selector_new_with_flags, success )
259
260 wxDL_METHOD_LOAD( m_gnome_printui_lib, gnome_print_job_preview_new, success )
261
262 m_ok = true;
263 }
264
265 static wxGnomePrintLibrary* gs_lgp = NULL;
266
267 //----------------------------------------------------------------------------
268 // wxGnomePrintNativeData
269 //----------------------------------------------------------------------------
270
271 IMPLEMENT_CLASS(wxGnomePrintNativeData, wxPrintNativeDataBase)
272
273 wxGnomePrintNativeData::wxGnomePrintNativeData()
274 {
275 m_config = gs_lgp->gnome_print_config_default();
276 m_job = gs_lgp->gnome_print_job_new( m_config );
277 }
278
279 wxGnomePrintNativeData::~wxGnomePrintNativeData()
280 {
281 g_object_unref (G_OBJECT (m_config));
282 }
283
284 bool wxGnomePrintNativeData::TransferTo( wxPrintData &data )
285 {
286 // TODO
287 return true;
288 }
289
290 bool wxGnomePrintNativeData::TransferFrom( const wxPrintData &data )
291 {
292 // TODO
293 return true;
294 }
295
296 //----------------------------------------------------------------------------
297 // wxGnomePrintFactory
298 //----------------------------------------------------------------------------
299
300 wxPrinterBase* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData *data )
301 {
302 return new wxGnomePrinter( data );
303 }
304
305 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
306 wxPrintout *printout,
307 wxPrintDialogData *data )
308 {
309 return new wxPostScriptPrintPreview( preview, printout, data );
310 }
311
312 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
313 wxPrintout *printout,
314 wxPrintData *data )
315 {
316 return new wxPostScriptPrintPreview( preview, printout, data );
317 }
318
319 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
320 wxPrintDialogData *data )
321 {
322 return new wxGnomePrintDialog( parent, data );
323 }
324
325 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
326 wxPrintData *data )
327 {
328 return new wxGnomePrintDialog( parent, data );
329 }
330
331 wxPageSetupDialogBase *wxGnomePrintFactory::CreatePageSetupDialog( wxWindow *parent,
332 wxPageSetupDialogData * data )
333 {
334 // The native page setup dialog is broken. It
335 // miscalculates newly entered values for the
336 // margins if you have not chose "points" but
337 // e.g. centimerters.
338 // This has been fixed in GNOME CVS (maybe
339 // fixed in libgnomeprintui 2.8.1)
340
341 return new wxGnomePageSetupDialog( parent, data );
342 }
343
344 bool wxGnomePrintFactory::HasPrintSetupDialog()
345 {
346 return false;
347 }
348
349 wxDialog *wxGnomePrintFactory::CreatePrintSetupDialog( wxWindow *parent, wxPrintData *data )
350 {
351 return NULL;
352 }
353
354 bool wxGnomePrintFactory::HasOwnPrintToFile()
355 {
356 return true;
357 }
358
359 bool wxGnomePrintFactory::HasPrinterLine()
360 {
361 return true;
362 }
363
364 wxString wxGnomePrintFactory::CreatePrinterLine()
365 {
366 // redundant now
367 return wxEmptyString;
368 }
369
370 bool wxGnomePrintFactory::HasStatusLine()
371 {
372 // redundant now
373 return true;
374 }
375
376 wxString wxGnomePrintFactory::CreateStatusLine()
377 {
378 // redundant now
379 return wxEmptyString;
380 }
381
382 wxPrintNativeDataBase *wxGnomePrintFactory::CreatePrintNativeData()
383 {
384 return new wxGnomePrintNativeData;
385 }
386
387 //----------------------------------------------------------------------------
388 // wxGnomePrintSetupDialog
389 //----------------------------------------------------------------------------
390
391 IMPLEMENT_CLASS(wxGnomePrintDialog, wxPrintDialogBase)
392
393 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow *parent, wxPrintDialogData *data )
394 : wxPrintDialogBase(parent, wxID_ANY, _("Print"),
395 wxPoint(0, 0), wxSize(600, 600),
396 wxDEFAULT_DIALOG_STYLE |
397 wxTAB_TRAVERSAL)
398 {
399 if (data)
400 m_printDialogData = *data;
401
402 Init();
403 }
404
405 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow *parent, wxPrintData *data )
406 : wxPrintDialogBase(parent, wxID_ANY, _("Print"),
407 wxPoint(0, 0), wxSize(600, 600),
408 wxDEFAULT_DIALOG_STYLE |
409 wxTAB_TRAVERSAL)
410 {
411 if (data)
412 m_printDialogData = *data;
413
414 Init();
415 }
416
417 void wxGnomePrintDialog::Init()
418 {
419 wxPrintData data = m_printDialogData.GetPrintData();
420
421 wxGnomePrintNativeData *native =
422 (wxGnomePrintNativeData*) data.GetNativeData();
423
424 m_widget = gs_lgp->gnome_print_dialog_new( native->GetPrintJob(),
425 (guchar*)"Print",
426 GNOME_PRINT_DIALOG_RANGE|GNOME_PRINT_DIALOG_COPIES );
427
428 int flag = 0;
429 if (m_printDialogData.GetEnableSelection())
430 flag |= GNOME_PRINT_RANGE_SELECTION;
431 if (m_printDialogData.GetEnablePageNumbers())
432 flag |= GNOME_PRINT_RANGE_ALL|GNOME_PRINT_RANGE_RANGE;
433
434 gs_lgp->gnome_print_dialog_construct_range_page( (GnomePrintDialog*) m_widget,
435 flag,
436 m_printDialogData.GetMinPage(),
437 m_printDialogData.GetMaxPage(),
438 NULL,
439 NULL );
440 }
441
442 wxGnomePrintDialog::~wxGnomePrintDialog()
443 {
444 m_widget = NULL;
445 }
446
447 int wxGnomePrintDialog::ShowModal()
448 {
449 // Transfer data from m_printDalogData to dialog here
450
451 int response = gtk_dialog_run (GTK_DIALOG (m_widget));
452
453 if (response == GNOME_PRINT_DIALOG_RESPONSE_CANCEL)
454 {
455 gtk_widget_destroy(m_widget);
456 m_widget = NULL;
457
458 return wxID_CANCEL;
459 }
460
461 gint copies = 1;
462 gboolean collate = false;
463 gs_lgp->gnome_print_dialog_get_copies( (GnomePrintDialog*) m_widget, &copies, &collate );
464 m_printDialogData.SetNoCopies( copies );
465 m_printDialogData.SetCollate( collate );
466
467 switch (gs_lgp->gnome_print_dialog_get_range( (GnomePrintDialog*) m_widget ))
468 {
469 case GNOME_PRINT_RANGE_SELECTION:
470 m_printDialogData.SetSelection( true );
471 break;
472 case GNOME_PRINT_RANGE_ALL:
473 m_printDialogData.SetAllPages( true );
474 m_printDialogData.SetFromPage( 0 );
475 m_printDialogData.SetToPage( 9999 );
476 break;
477 case GNOME_PRINT_RANGE_RANGE:
478 default:
479 gint start,end;
480 gs_lgp->gnome_print_dialog_get_range_page( (GnomePrintDialog*) m_widget, &start, &end );
481 m_printDialogData.SetFromPage( start );
482 m_printDialogData.SetToPage( end );
483 break;
484 }
485
486 gtk_widget_destroy(m_widget);
487 m_widget = NULL;
488
489 if (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW)
490 return wxID_PREVIEW;
491
492 return wxID_OK;
493 }
494
495 wxDC *wxGnomePrintDialog::GetPrintDC()
496 {
497 // Later
498 return NULL;
499 }
500
501 bool wxGnomePrintDialog::Validate()
502 {
503 return true;
504 }
505
506 bool wxGnomePrintDialog::TransferDataToWindow()
507 {
508 return true;
509 }
510
511 bool wxGnomePrintDialog::TransferDataFromWindow()
512 {
513 return true;
514 }
515
516 //----------------------------------------------------------------------------
517 // wxGnomePageSetupDialog
518 //----------------------------------------------------------------------------
519
520 IMPLEMENT_CLASS(wxGnomePageSetupDialog, wxPageSetupDialogBase)
521
522 wxGnomePageSetupDialog::wxGnomePageSetupDialog( wxWindow *parent,
523 wxPageSetupDialogData* data )
524 {
525 if (data)
526 m_pageDialogData = *data;
527
528 wxGnomePrintNativeData *native =
529 (wxGnomePrintNativeData*) m_pageDialogData.GetPrintData().GetNativeData();
530
531 // This is required as the page setup dialog
532 // calculates wrong values otherwise.
533 gs_lgp->gnome_print_config_set( native->GetPrintConfig(),
534 (const guchar*) GNOME_PRINT_KEY_PREFERED_UNIT,
535 (const guchar*) "Pts" );
536
537 m_widget = gtk_dialog_new();
538
539 gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( _("Page setup") ) );
540
541 GtkWidget *main = gs_lgp->gnome_paper_selector_new_with_flags( native->GetPrintConfig(),
542 GNOME_PAPER_SELECTOR_MARGINS|GNOME_PAPER_SELECTOR_FEED_ORIENTATION );
543 gtk_container_set_border_width (GTK_CONTAINER (main), 8);
544 gtk_widget_show (main);
545
546 gtk_container_add( GTK_CONTAINER (GTK_DIALOG (m_widget)->vbox), main );
547
548 gtk_dialog_set_has_separator (GTK_DIALOG (m_widget), TRUE);
549
550 gtk_dialog_add_buttons (GTK_DIALOG (m_widget),
551 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
552 GTK_STOCK_OK, GTK_RESPONSE_OK,
553 NULL);
554
555 gtk_dialog_set_default_response (GTK_DIALOG (m_widget),
556 GTK_RESPONSE_OK);
557 }
558
559 wxGnomePageSetupDialog::~wxGnomePageSetupDialog()
560 {
561 }
562
563 wxPageSetupDialogData& wxGnomePageSetupDialog::GetPageSetupDialogData()
564 {
565 return m_pageDialogData;
566 }
567
568 int wxGnomePageSetupDialog::ShowModal()
569 {
570 wxGnomePrintNativeData *native =
571 (wxGnomePrintNativeData*) m_pageDialogData.GetPrintData().GetNativeData();
572 GnomePrintConfig *config = native->GetPrintConfig();
573
574 // Transfer data from m_pageDialogData to native dialog
575
576 int ret = gtk_dialog_run( GTK_DIALOG(m_widget) );
577
578 if (ret == GTK_RESPONSE_OK)
579 {
580 // Transfer data back to m_pageDialogData
581
582 // I don't know how querying the last parameter works
583 // I cannot test it as the dialog is currently broken
584 // anyways (it only works for points).
585 double ml,mr,mt,mb,pw,ph;
586 gs_lgp->gnome_print_config_get_length (config,
587 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_LEFT, &ml, NULL);
588 gs_lgp->gnome_print_config_get_length (config,
589 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT, &mr, NULL);
590 gs_lgp->gnome_print_config_get_length (config,
591 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_TOP, &mt, NULL);
592 gs_lgp->gnome_print_config_get_length (config,
593 (const guchar*) GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM, &mb, NULL);
594 gs_lgp->gnome_print_config_get_length (config,
595 (const guchar*) GNOME_PRINT_KEY_PAPER_WIDTH, &pw, NULL);
596 gs_lgp->gnome_print_config_get_length (config,
597 (const guchar*) GNOME_PRINT_KEY_PAPER_HEIGHT, &ph, NULL);
598
599 // This probably assumes that the user entered the
600 // values in Pts. Since that is the only the dialog
601 // works right now, we need to fix this later.
602 const GnomePrintUnit *mm_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "mm" );
603 const GnomePrintUnit *pts_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "Pts" );
604 gs_lgp->gnome_print_convert_distance( &ml, pts_unit, mm_unit );
605 gs_lgp->gnome_print_convert_distance( &mr, pts_unit, mm_unit );
606 gs_lgp->gnome_print_convert_distance( &mt, pts_unit, mm_unit );
607 gs_lgp->gnome_print_convert_distance( &mb, pts_unit, mm_unit );
608 gs_lgp->gnome_print_convert_distance( &pw, pts_unit, mm_unit );
609 gs_lgp->gnome_print_convert_distance( &ph, pts_unit, mm_unit );
610
611 m_pageDialogData.SetMarginTopLeft( wxPoint( (int)(ml+0.5), (int)(mt+0.5)) );
612 m_pageDialogData.SetMarginBottomRight( wxPoint( (int)(mr+0.5), (int)(mb+0.5)) );
613
614 m_pageDialogData.SetPaperSize( wxSize( (int)(pw+0.5), (int)(ph+0.5) ) );
615
616 #if 0
617 wxPrintf( wxT("paper %d %d, top margin %d\n"),
618 m_pageDialogData.GetPaperSize().x,
619 m_pageDialogData.GetPaperSize().y,
620 m_pageDialogData.GetMarginTopLeft().x );
621 #endif
622
623 ret = wxID_OK;
624 }
625 else
626 {
627 ret = wxID_CANCEL;
628 }
629
630 gtk_widget_destroy( m_widget );
631 m_widget = NULL;
632
633 return ret;
634 }
635
636 bool wxGnomePageSetupDialog::Validate()
637 {
638 return true;
639 }
640
641 bool wxGnomePageSetupDialog::TransferDataToWindow()
642 {
643 return true;
644 }
645
646 bool wxGnomePageSetupDialog::TransferDataFromWindow()
647 {
648 return true;
649 }
650
651 //----------------------------------------------------------------------------
652 // wxGnomePrinter
653 //----------------------------------------------------------------------------
654
655 IMPLEMENT_CLASS(wxGnomePrinter, wxPrinterBase)
656
657 wxGnomePrinter::wxGnomePrinter( wxPrintDialogData *data ) :
658 wxPrinterBase( data )
659 {
660 m_gpc = NULL;
661 m_native_preview = false;
662 }
663
664 wxGnomePrinter::~wxGnomePrinter()
665 {
666 }
667
668 bool wxGnomePrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt )
669 {
670 if (!printout)
671 {
672 sm_lastError = wxPRINTER_ERROR;
673 return false;
674 }
675
676 wxPrintData printdata = GetPrintDialogData().GetPrintData();
677 wxGnomePrintNativeData *native =
678 (wxGnomePrintNativeData*) printdata.GetNativeData();
679
680 GnomePrintJob *job = gs_lgp->gnome_print_job_new( native->GetPrintConfig() );
681 m_gpc = gs_lgp->gnome_print_job_get_context (job);
682
683 // The GnomePrintJob is temporarily stored in the
684 // native print data as the native print dialog
685 // needs to access it.
686 native->SetPrintJob( job );
687
688
689 printout->SetIsPreview(false);
690
691 if (m_printDialogData.GetMinPage() < 1)
692 m_printDialogData.SetMinPage(1);
693 if (m_printDialogData.GetMaxPage() < 1)
694 m_printDialogData.SetMaxPage(9999);
695
696 wxDC *dc;
697 if (prompt)
698 dc = PrintDialog( parent );
699 else
700 dc = new wxGnomePrintDC( this );
701
702 if (m_native_preview)
703 printout->SetIsPreview(true);
704
705 if (!dc)
706 {
707 gs_lgp->gnome_print_job_close( job );
708 g_object_unref (G_OBJECT (job));
709 sm_lastError = wxPRINTER_ERROR;
710 return false;
711 }
712
713 wxSize ScreenPixels = wxGetDisplaySize();
714 wxSize ScreenMM = wxGetDisplaySizeMM();
715
716 printout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()),
717 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) );
718 printout->SetPPIPrinter( wxGnomePrintDC::GetResolution(),
719 wxGnomePrintDC::GetResolution() );
720
721 printout->SetDC(dc);
722
723 int w, h;
724 dc->GetSize(&w, &h);
725 printout->SetPageSizePixels((int)w, (int)h);
726 dc->GetSizeMM(&w, &h);
727 printout->SetPageSizeMM((int)w, (int)h);
728
729 printout->OnPreparePrinting();
730
731 // Get some parameters from the printout, if defined
732 int fromPage, toPage;
733 int minPage, maxPage;
734 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
735
736 if (maxPage == 0)
737 {
738 gs_lgp->gnome_print_job_close( job );
739 g_object_unref (G_OBJECT (job));
740 sm_lastError = wxPRINTER_ERROR;
741 return false;
742 }
743
744 printout->OnBeginPrinting();
745
746 int minPageNum = minPage, maxPageNum = maxPage;
747
748 if ( !m_printDialogData.GetAllPages() )
749 {
750 minPageNum = m_printDialogData.GetFromPage();
751 maxPageNum = m_printDialogData.GetToPage();
752 }
753
754
755 int copyCount;
756 for ( copyCount = 1;
757 copyCount <= m_printDialogData.GetNoCopies();
758 copyCount++ )
759 {
760 if (!printout->OnBeginDocument(minPageNum, maxPageNum))
761 {
762 wxLogError(_("Could not start printing."));
763 sm_lastError = wxPRINTER_ERROR;
764 break;
765 }
766
767 int pn;
768 for ( pn = minPageNum;
769 pn <= maxPageNum && printout->HasPage(pn);
770 pn++ )
771 {
772 dc->StartPage();
773 printout->OnPrintPage(pn);
774 dc->EndPage();
775 }
776
777 printout->OnEndDocument();
778 printout->OnEndPrinting();
779 }
780
781 gs_lgp->gnome_print_job_close( job );
782 if (m_native_preview)
783 {
784 wxString title( _("Print preview") );
785 gtk_widget_show( gs_lgp->gnome_print_job_preview_new( job, (const guchar*)(const char*)wxGTK_CONV(title) ));
786 }
787 else
788 {
789 gs_lgp->gnome_print_job_print( job );
790 }
791
792 g_object_unref (G_OBJECT (job));
793 delete dc;
794
795 return (sm_lastError == wxPRINTER_NO_ERROR);
796 }
797
798 wxDC* wxGnomePrinter::PrintDialog( wxWindow *parent )
799 {
800 wxGnomePrintDialog dialog( parent, &m_printDialogData );
801 int ret = dialog.ShowModal();
802 if (ret == wxID_CANCEL)
803 {
804 sm_lastError = wxPRINTER_CANCELLED;
805 return NULL;
806 }
807
808 m_native_preview = ret == wxID_PREVIEW;
809
810 m_printDialogData = dialog.GetPrintDialogData();
811 return new wxGnomePrintDC( this );
812 }
813
814 bool wxGnomePrinter::Setup( wxWindow *parent )
815 {
816 return false;
817 }
818
819 //-----------------------------------------------------------------------------
820 // wxGnomePrintDC
821 //-----------------------------------------------------------------------------
822
823 IMPLEMENT_CLASS(wxGnomePrintDC, wxDC)
824
825 wxGnomePrintDC::wxGnomePrintDC( wxGnomePrinter *printer )
826 {
827 m_printer = printer;
828
829 m_gpc = printer->GetPrintContext();
830
831 m_layout = gs_lgp->gnome_print_pango_create_layout( m_gpc );
832 m_fontdesc = pango_font_description_from_string( "Sans 12" );
833
834 m_currentRed = 0;
835 m_currentBlue = 0;
836 m_currentGreen = 0;
837
838 m_signX = 1; // default x-axis left to right
839 m_signY = -1; // default y-axis bottom up -> top down
840 }
841
842 wxGnomePrintDC::~wxGnomePrintDC()
843 {
844 }
845
846 bool wxGnomePrintDC::Ok() const
847 {
848 return true;
849 }
850
851 bool wxGnomePrintDC::DoFloodFill(wxCoord x1, wxCoord y1, const wxColour &col, int style )
852 {
853 return false;
854 }
855
856 bool wxGnomePrintDC::DoGetPixel(wxCoord x1, wxCoord y1, wxColour *col) const
857 {
858 return false;
859 }
860
861 void wxGnomePrintDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
862 {
863 if (m_pen.GetStyle() == wxTRANSPARENT) return;
864
865 SetPen( m_pen );
866
867 gs_lgp->gnome_print_moveto ( m_gpc, XLOG2DEV(x1), YLOG2DEV(y1) );
868 gs_lgp->gnome_print_lineto ( m_gpc, XLOG2DEV(x2), YLOG2DEV(y2) );
869 gs_lgp->gnome_print_stroke ( m_gpc);
870
871 CalcBoundingBox( x1, y1 );
872 CalcBoundingBox( x2, y2 );
873 }
874
875 void wxGnomePrintDC::DoCrossHair(wxCoord x, wxCoord y)
876 {
877 }
878
879 void wxGnomePrintDC::DoDrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2,wxCoord xc,wxCoord yc)
880 {
881 }
882
883 void wxGnomePrintDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)
884 {
885 x += w/2;
886 y += h/2;
887
888 int xx = XLOG2DEV(x);
889 int yy = YLOG2DEV(y);
890
891 gs_lgp->gnome_print_gsave( m_gpc );
892
893 gs_lgp->gnome_print_translate( m_gpc, xx, yy );
894 double scale = (double)YLOG2DEVREL(h) / (double) XLOG2DEVREL(w);
895 gs_lgp->gnome_print_scale( m_gpc, 1.0, scale );
896
897 xx = 0;
898 yy = 0;
899
900 if (m_brush.GetStyle () != wxTRANSPARENT)
901 {
902 SetBrush( m_brush );
903
904 gs_lgp->gnome_print_moveto ( m_gpc, xx, yy );
905 gs_lgp->gnome_print_arcto( m_gpc, xx, yy,
906 XLOG2DEVREL(w)/2, sa, ea, 0 );
907 gs_lgp->gnome_print_moveto ( m_gpc, xx, yy );
908
909 gs_lgp->gnome_print_fill( m_gpc );
910 }
911
912 if (m_pen.GetStyle () != wxTRANSPARENT)
913 {
914 SetPen (m_pen);
915
916 gs_lgp->gnome_print_arcto( m_gpc, xx, yy,
917 XLOG2DEVREL(w)/2, sa, ea, 0 );
918
919 gs_lgp->gnome_print_stroke( m_gpc );
920 }
921
922 gs_lgp->gnome_print_grestore( m_gpc );
923
924 CalcBoundingBox( x, y );
925 CalcBoundingBox( x+w, y+h );
926 }
927
928 void wxGnomePrintDC::DoDrawPoint(wxCoord x, wxCoord y)
929 {
930 }
931
932 void wxGnomePrintDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset)
933 {
934 if (m_pen.GetStyle() == wxTRANSPARENT) return;
935
936 if (n <= 0) return;
937
938 SetPen (m_pen);
939
940 int i;
941 for ( i =0; i<n ; i++ )
942 CalcBoundingBox( points[i].x+xoffset, points[i].y+yoffset);
943
944 gs_lgp->gnome_print_moveto ( m_gpc, XLOG2DEV(points[0].x+xoffset), YLOG2DEV(points[0].y+yoffset) );
945
946 for (i = 1; i < n; i++)
947 gs_lgp->gnome_print_lineto ( m_gpc, XLOG2DEV(points[i].x+xoffset), YLOG2DEV(points[i].y+yoffset) );
948
949 gs_lgp->gnome_print_stroke ( m_gpc);
950 }
951
952 void wxGnomePrintDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
953 {
954 if (n==0) return;
955
956 if (m_brush.GetStyle () != wxTRANSPARENT)
957 {
958 SetBrush( m_brush );
959
960 int x = points[0].x + xoffset;
961 int y = points[0].y + yoffset;
962 CalcBoundingBox( x, y );
963 gs_lgp->gnome_print_newpath( m_gpc );
964 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
965 int i;
966 for (i = 1; i < n; i++)
967 {
968 int x = points[i].x + xoffset;
969 int y = points[i].y + yoffset;
970 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
971 CalcBoundingBox( x, y );
972 }
973 gs_lgp->gnome_print_closepath( m_gpc );
974 gs_lgp->gnome_print_fill( m_gpc );
975 }
976
977 if (m_pen.GetStyle () != wxTRANSPARENT)
978 {
979 SetPen (m_pen);
980
981 int x = points[0].x + xoffset;
982 int y = points[0].y + yoffset;
983 gs_lgp->gnome_print_newpath( m_gpc );
984 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
985 int i;
986 for (i = 1; i < n; i++)
987 {
988 int x = points[i].x + xoffset;
989 int y = points[i].y + yoffset;
990 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
991 CalcBoundingBox( x, y );
992 }
993 gs_lgp->gnome_print_closepath( m_gpc );
994 gs_lgp->gnome_print_stroke( m_gpc );
995 }
996 }
997
998 void wxGnomePrintDC::DoDrawPolyPolygon(int n, int count[], wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
999 {
1000 wxDC::DoDrawPolyPolygon( n, count, points, xoffset, yoffset, fillStyle );
1001 }
1002
1003 void wxGnomePrintDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
1004 {
1005 if (m_brush.GetStyle () != wxTRANSPARENT)
1006 {
1007 SetBrush( m_brush );
1008
1009 gs_lgp->gnome_print_newpath( m_gpc );
1010 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
1011 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
1012 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
1013 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
1014 gs_lgp->gnome_print_closepath( m_gpc );
1015 gs_lgp->gnome_print_fill( m_gpc );
1016
1017 CalcBoundingBox( x, y );
1018 CalcBoundingBox( x + width, y + height );
1019 }
1020
1021 if (m_pen.GetStyle () != wxTRANSPARENT)
1022 {
1023 SetPen (m_pen);
1024
1025 gs_lgp->gnome_print_newpath( m_gpc );
1026 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
1027 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
1028 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
1029 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
1030 gs_lgp->gnome_print_closepath( m_gpc );
1031 gs_lgp->gnome_print_stroke( m_gpc );
1032
1033 CalcBoundingBox( x, y );
1034 CalcBoundingBox( x + width, y + height );
1035 }
1036 }
1037
1038 void wxGnomePrintDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
1039 {
1040 wxCoord rad = (wxCoord) radius;
1041
1042 if (m_brush.GetStyle() != wxTRANSPARENT)
1043 {
1044 SetBrush(m_brush);
1045 gs_lgp->gnome_print_newpath(m_gpc);
1046 gs_lgp->gnome_print_moveto(m_gpc,XLOG2DEV(x + rad),YLOG2DEV(y));
1047 gs_lgp->gnome_print_curveto(m_gpc,
1048 XLOG2DEV(x + rad),YLOG2DEV(y),
1049 XLOG2DEV(x),YLOG2DEV(y),
1050 XLOG2DEV(x),YLOG2DEV(y + rad));
1051 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x),YLOG2DEV(y + height - rad));
1052 gs_lgp->gnome_print_curveto(m_gpc,
1053 XLOG2DEV(x),YLOG2DEV(y + height - rad),
1054 XLOG2DEV(x),YLOG2DEV(y + height),
1055 XLOG2DEV(x + rad),YLOG2DEV(y + height));
1056 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x + width - rad),YLOG2DEV(y + height));
1057 gs_lgp->gnome_print_curveto(m_gpc,
1058 XLOG2DEV(x + width - rad),YLOG2DEV(y + height),
1059 XLOG2DEV(x + width),YLOG2DEV(y + height),
1060 XLOG2DEV(x + width),YLOG2DEV(y + height - rad));
1061 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x + width),YLOG2DEV(y + rad));
1062 gs_lgp->gnome_print_curveto(m_gpc,
1063 XLOG2DEV(x + width),YLOG2DEV(y + rad),
1064 XLOG2DEV(x + width),YLOG2DEV(y),
1065 XLOG2DEV(x + width - rad),YLOG2DEV(y));
1066 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x + rad),YLOG2DEV(y));
1067 gs_lgp->gnome_print_closepath(m_gpc);
1068 gs_lgp->gnome_print_fill(m_gpc);
1069
1070 CalcBoundingBox(x,y);
1071 CalcBoundingBox(x+width,y+height);
1072 }
1073
1074 if (m_pen.GetStyle() != wxTRANSPARENT)
1075 {
1076 SetPen(m_pen);
1077 gs_lgp->gnome_print_newpath(m_gpc);
1078 gs_lgp->gnome_print_moveto(m_gpc,XLOG2DEV(x + rad),YLOG2DEV(y));
1079 gs_lgp->gnome_print_curveto(m_gpc,
1080 XLOG2DEV(x + rad),YLOG2DEV(y),
1081 XLOG2DEV(x),YLOG2DEV(y),
1082 XLOG2DEV(x),YLOG2DEV(y + rad));
1083 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x),YLOG2DEV(y + height - rad));
1084 gs_lgp->gnome_print_curveto(m_gpc,
1085 XLOG2DEV(x),YLOG2DEV(y + height - rad),
1086 XLOG2DEV(x),YLOG2DEV(y + height),
1087 XLOG2DEV(x + rad),YLOG2DEV(y + height));
1088 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x + width - rad),YLOG2DEV(y + height));
1089 gs_lgp->gnome_print_curveto(m_gpc,
1090 XLOG2DEV(x + width - rad),YLOG2DEV(y + height),
1091 XLOG2DEV(x + width),YLOG2DEV(y + height),
1092 XLOG2DEV(x + width),YLOG2DEV(y + height - rad));
1093 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x + width),YLOG2DEV(y + rad));
1094 gs_lgp->gnome_print_curveto(m_gpc,
1095 XLOG2DEV(x + width),YLOG2DEV(y + rad),
1096 XLOG2DEV(x + width),YLOG2DEV(y),
1097 XLOG2DEV(x + width - rad),YLOG2DEV(y));
1098 gs_lgp->gnome_print_lineto(m_gpc,XLOG2DEV(x + rad),YLOG2DEV(y));
1099 gs_lgp->gnome_print_closepath(m_gpc);
1100 gs_lgp->gnome_print_stroke(m_gpc);
1101
1102 CalcBoundingBox(x,y);
1103 CalcBoundingBox(x+width,y+height);
1104 }
1105 }
1106
1107 void wxGnomePrintDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
1108 {
1109 if (m_brush.GetStyle () != wxTRANSPARENT)
1110 {
1111 SetBrush( m_brush );
1112
1113 gs_lgp->gnome_print_newpath( m_gpc );
1114 gs_lgp->gnome_print_moveto( m_gpc,
1115 XLOG2DEV(x), YLOG2DEV(y+height/2) );
1116
1117 // start with top half
1118 gs_lgp->gnome_print_curveto( m_gpc,
1119 XLOG2DEV(x), YLOG2DEV(y),
1120 XLOG2DEV(x+width), YLOG2DEV(y),
1121 XLOG2DEV(x+width), YLOG2DEV(y+height/2) );
1122 // lower half
1123 gs_lgp->gnome_print_curveto( m_gpc,
1124 XLOG2DEV(x+width), YLOG2DEV(y+height),
1125 XLOG2DEV(x), YLOG2DEV(y+height),
1126 XLOG2DEV(x), YLOG2DEV(y+height/2) );
1127
1128 gs_lgp->gnome_print_closepath( m_gpc );
1129 gs_lgp->gnome_print_fill( m_gpc );
1130
1131 CalcBoundingBox( x, y );
1132 CalcBoundingBox( x + width, y + height );
1133 }
1134
1135 if (m_pen.GetStyle () != wxTRANSPARENT)
1136 {
1137 SetPen (m_pen);
1138
1139 gs_lgp->gnome_print_newpath( m_gpc );
1140 gs_lgp->gnome_print_moveto( m_gpc,
1141 XLOG2DEV(x), YLOG2DEV(y+height/2) );
1142
1143 // start with top half
1144 gs_lgp->gnome_print_curveto( m_gpc,
1145 XLOG2DEV(x), YLOG2DEV(y),
1146 XLOG2DEV(x+width), YLOG2DEV(y),
1147 XLOG2DEV(x+width), YLOG2DEV(y+height/2) );
1148 // lower half
1149 gs_lgp->gnome_print_curveto( m_gpc,
1150 XLOG2DEV(x+width), YLOG2DEV(y+height),
1151 XLOG2DEV(x), YLOG2DEV(y+height),
1152 XLOG2DEV(x), YLOG2DEV(y+height/2) );
1153
1154 gs_lgp->gnome_print_closepath( m_gpc );
1155 gs_lgp->gnome_print_stroke( m_gpc );
1156
1157 CalcBoundingBox( x, y );
1158 CalcBoundingBox( x + width, y + height );
1159 }
1160 }
1161
1162 void wxGnomePrintDC::DoDrawSpline(wxList *points)
1163 {
1164 SetPen (m_pen);
1165
1166 double c, d, x1, y1, x2, y2, x3, y3;
1167 wxPoint *p, *q;
1168
1169 wxList::compatibility_iterator node = points->GetFirst();
1170 p = (wxPoint *)node->GetData();
1171 x1 = p->x;
1172 y1 = p->y;
1173
1174 node = node->GetNext();
1175 p = (wxPoint *)node->GetData();
1176 c = p->x;
1177 d = p->y;
1178 x3 =
1179 (double)(x1 + c) / 2;
1180 y3 =
1181 (double)(y1 + d) / 2;
1182
1183 gs_lgp->gnome_print_newpath( m_gpc );
1184 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV((wxCoord)x1), YLOG2DEV((wxCoord)y1) );
1185 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV((wxCoord)x3), YLOG2DEV((wxCoord)y3) );
1186
1187 CalcBoundingBox( (wxCoord)x1, (wxCoord)y1 );
1188 CalcBoundingBox( (wxCoord)x3, (wxCoord)y3 );
1189
1190 node = node->GetNext();
1191 while (node)
1192 {
1193 q = (wxPoint *)node->GetData();
1194
1195 x1 = x3;
1196 y1 = y3;
1197 x2 = c;
1198 y2 = d;
1199 c = q->x;
1200 d = q->y;
1201 x3 = (double)(x2 + c) / 2;
1202 y3 = (double)(y2 + d) / 2;
1203
1204 gs_lgp->gnome_print_curveto(m_gpc,
1205 XLOG2DEV((wxCoord)x1), YLOG2DEV((wxCoord)y1),
1206 XLOG2DEV((wxCoord)x2), YLOG2DEV((wxCoord)y2),
1207 XLOG2DEV((wxCoord)x3), YLOG2DEV((wxCoord)y3) );
1208
1209 CalcBoundingBox( (wxCoord)x1, (wxCoord)y1 );
1210 CalcBoundingBox( (wxCoord)x3, (wxCoord)y3 );
1211
1212 node = node->GetNext();
1213 }
1214
1215 gs_lgp->gnome_print_lineto ( m_gpc, XLOG2DEV((wxCoord)c), YLOG2DEV((wxCoord)d) );
1216
1217 gs_lgp->gnome_print_stroke( m_gpc );
1218 }
1219
1220 bool wxGnomePrintDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
1221 wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
1222 wxCoord xsrcMask, wxCoord ysrcMask)
1223 {
1224 return false;
1225 }
1226
1227 void wxGnomePrintDC::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
1228 {
1229 DoDrawBitmap( icon, x, y, true );
1230 }
1231
1232 void wxGnomePrintDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool useMask )
1233 {
1234 if (!bitmap.Ok()) return;
1235
1236 if (bitmap.HasPixbuf())
1237 {
1238 GdkPixbuf *pixbuf = bitmap.GetPixbuf();
1239 guchar *raw_image = gdk_pixbuf_get_pixels( pixbuf );
1240 bool has_alpha = gdk_pixbuf_get_has_alpha( pixbuf );
1241 int rowstride = gdk_pixbuf_get_rowstride( pixbuf );
1242 int height = gdk_pixbuf_get_height( pixbuf );
1243 int width = gdk_pixbuf_get_width( pixbuf );
1244
1245 gs_lgp->gnome_print_gsave( m_gpc );
1246 double matrix[6];
1247 matrix[0] = XLOG2DEVREL(width);
1248 matrix[1] = 0;
1249 matrix[2] = 0;
1250 matrix[3] = YLOG2DEVREL(height);
1251 matrix[4] = XLOG2DEV(x);
1252 matrix[5] = YLOG2DEV(y+height);
1253 gs_lgp->gnome_print_concat( m_gpc, matrix );
1254 gs_lgp->gnome_print_moveto( m_gpc, 0, 0 );
1255 if (has_alpha)
1256 gs_lgp->gnome_print_rgbaimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
1257 else
1258 gs_lgp->gnome_print_rgbimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
1259 gs_lgp->gnome_print_grestore( m_gpc );
1260 }
1261 else
1262 {
1263 wxImage image = bitmap.ConvertToImage();
1264
1265 if (!image.Ok()) return;
1266
1267 gs_lgp->gnome_print_gsave( m_gpc );
1268 double matrix[6];
1269 matrix[0] = XLOG2DEVREL(image.GetWidth());
1270 matrix[1] = 0;
1271 matrix[2] = 0;
1272 matrix[3] = YLOG2DEVREL(image.GetHeight());
1273 matrix[4] = XLOG2DEV(x);
1274 matrix[5] = YLOG2DEV(y+image.GetHeight());
1275 gs_lgp->gnome_print_concat( m_gpc, matrix );
1276 gs_lgp->gnome_print_moveto( m_gpc, 0, 0 );
1277 gs_lgp->gnome_print_rgbimage( m_gpc, (guchar*) image.GetData(), image.GetWidth(), image.GetHeight(), image.GetWidth()*3 );
1278 gs_lgp->gnome_print_grestore( m_gpc );
1279 }
1280 }
1281
1282 void wxGnomePrintDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y )
1283 {
1284 DoDrawRotatedText( text, x, y, 0.0 );
1285 }
1286
1287 void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
1288 {
1289 x = XLOG2DEV(x);
1290 y = YLOG2DEV(y);
1291
1292 bool underlined = m_font.Ok() && m_font.GetUnderlined();
1293
1294 #if wxUSE_UNICODE
1295 const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
1296 #else
1297 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text );
1298 if ( !wdata )
1299 return;
1300 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1301 #endif
1302
1303 size_t datalen = strlen((const char*)data);
1304 pango_layout_set_text( m_layout, (const char*) data, datalen);
1305
1306 if (underlined)
1307 {
1308 PangoAttrList *attrs = pango_attr_list_new();
1309 PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
1310 a->start_index = 0;
1311 a->end_index = datalen;
1312 pango_attr_list_insert(attrs, a);
1313 pango_layout_set_attributes(m_layout, attrs);
1314 pango_attr_list_unref(attrs);
1315 }
1316
1317 if (m_textForegroundColour.Ok())
1318 {
1319 unsigned char red = m_textForegroundColour.Red();
1320 unsigned char blue = m_textForegroundColour.Blue();
1321 unsigned char green = m_textForegroundColour.Green();
1322
1323 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1324 {
1325 double redPS = (double)(red) / 255.0;
1326 double bluePS = (double)(blue) / 255.0;
1327 double greenPS = (double)(green) / 255.0;
1328
1329 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1330
1331 m_currentRed = red;
1332 m_currentBlue = blue;
1333 m_currentGreen = green;
1334 }
1335 }
1336
1337 int w,h;
1338
1339 if (fabs(m_scaleY - 1.0) > 0.00001)
1340 {
1341 // If there is a user or actually any scale applied to
1342 // the device context, scale the font.
1343
1344 // scale font description
1345 gint oldSize = pango_font_description_get_size( m_fontdesc );
1346 double size = oldSize;
1347 size = size * m_scaleY;
1348 pango_font_description_set_size( m_fontdesc, (gint)size );
1349
1350 // actually apply scaled font
1351 pango_layout_set_font_description( m_layout, m_fontdesc );
1352
1353 pango_layout_get_pixel_size( m_layout, &w, &h );
1354 #if 0
1355 if ( m_backgroundMode == wxSOLID )
1356 {
1357 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1358 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
1359 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1360 }
1361 #endif
1362 // Draw layout.
1363 gs_lgp->gnome_print_moveto (m_gpc, x, y);
1364 if (fabs(angle) > 0.00001)
1365 {
1366 gs_lgp->gnome_print_gsave( m_gpc );
1367 gs_lgp->gnome_print_rotate( m_gpc, angle );
1368 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1369 gs_lgp->gnome_print_grestore( m_gpc );
1370 }
1371 else
1372 {
1373 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1374 }
1375
1376 // reset unscaled size
1377 pango_font_description_set_size( m_fontdesc, oldSize );
1378
1379 // actually apply unscaled font
1380 pango_layout_set_font_description( m_layout, m_fontdesc );
1381 }
1382 else
1383 {
1384 pango_layout_get_pixel_size( m_layout, &w, &h );
1385 #if 0
1386 if ( m_backgroundMode == wxSOLID )
1387 {
1388 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1389 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
1390 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1391 }
1392 #endif
1393 // Draw layout.
1394 gs_lgp->gnome_print_moveto (m_gpc, x, y);
1395 if (fabs(angle) > 0.00001)
1396 {
1397 gs_lgp->gnome_print_gsave( m_gpc );
1398 gs_lgp->gnome_print_rotate( m_gpc, angle );
1399 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1400 gs_lgp->gnome_print_grestore( m_gpc );
1401 }
1402 else
1403 {
1404 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1405 }
1406 }
1407
1408 if (underlined)
1409 {
1410 // undo underline attributes setting:
1411 pango_layout_set_attributes(m_layout, NULL);
1412 }
1413
1414 CalcBoundingBox (x + w, y + h);
1415 }
1416
1417 void wxGnomePrintDC::Clear()
1418 {
1419 }
1420
1421 void wxGnomePrintDC::SetFont( const wxFont& font )
1422 {
1423 m_font = font;
1424
1425 if (m_font.Ok())
1426 {
1427 if (m_fontdesc)
1428 pango_font_description_free( m_fontdesc );
1429
1430 m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description );
1431
1432 pango_layout_set_font_description( m_layout, m_fontdesc );
1433 }
1434 }
1435
1436 void wxGnomePrintDC::SetPen( const wxPen& pen )
1437 {
1438 if (!pen.Ok()) return;
1439
1440 m_pen = pen;
1441
1442 gs_lgp->gnome_print_setlinewidth( m_gpc, XLOG2DEVREL( 1000 * m_pen.GetWidth() ) / 1000.0f );
1443
1444 static const double dotted[] = {2.0, 5.0};
1445 static const double short_dashed[] = {4.0, 4.0};
1446 static const double wxCoord_dashed[] = {4.0, 8.0};
1447 static const double dotted_dashed[] = {6.0, 6.0, 2.0, 6.0};
1448
1449 switch (m_pen.GetStyle())
1450 {
1451 case wxDOT: gs_lgp->gnome_print_setdash( m_gpc, 2, dotted, 0 ); break;
1452 case wxSHORT_DASH: gs_lgp->gnome_print_setdash( m_gpc, 2, short_dashed, 0 ); break;
1453 case wxLONG_DASH: gs_lgp->gnome_print_setdash( m_gpc, 2, wxCoord_dashed, 0 ); break;
1454 case wxDOT_DASH: gs_lgp->gnome_print_setdash( m_gpc, 4, dotted_dashed, 0 ); break;
1455 case wxSOLID:
1456 case wxTRANSPARENT:
1457 default: gs_lgp->gnome_print_setdash( m_gpc, 0, NULL, 0 ); break;
1458 }
1459
1460
1461 unsigned char red = m_pen.GetColour().Red();
1462 unsigned char blue = m_pen.GetColour().Blue();
1463 unsigned char green = m_pen.GetColour().Green();
1464
1465 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1466 {
1467 double redPS = (double)(red) / 255.0;
1468 double bluePS = (double)(blue) / 255.0;
1469 double greenPS = (double)(green) / 255.0;
1470
1471 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1472
1473 m_currentRed = red;
1474 m_currentBlue = blue;
1475 m_currentGreen = green;
1476 }
1477 }
1478
1479 void wxGnomePrintDC::SetBrush( const wxBrush& brush )
1480 {
1481 if (!brush.Ok()) return;
1482
1483 m_brush = brush;
1484
1485 // Brush colour
1486 unsigned char red = m_brush.GetColour().Red();
1487 unsigned char blue = m_brush.GetColour().Blue();
1488 unsigned char green = m_brush.GetColour().Green();
1489
1490 if (!m_colour)
1491 {
1492 // Anything not white is black
1493 if (! (red == (unsigned char) 255 &&
1494 blue == (unsigned char) 255 &&
1495 green == (unsigned char) 255) )
1496 {
1497 red = (unsigned char) 0;
1498 green = (unsigned char) 0;
1499 blue = (unsigned char) 0;
1500 }
1501 // setgray here ?
1502 }
1503
1504 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1505 {
1506 double redPS = (double)(red) / 255.0;
1507 double bluePS = (double)(blue) / 255.0;
1508 double greenPS = (double)(green) / 255.0;
1509
1510 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1511
1512 m_currentRed = red;
1513 m_currentBlue = blue;
1514 m_currentGreen = green;
1515 }
1516 }
1517
1518 void wxGnomePrintDC::SetLogicalFunction( int function )
1519 {
1520 }
1521
1522 void wxGnomePrintDC::SetBackground( const wxBrush& brush )
1523 {
1524 }
1525
1526 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
1527 {
1528 }
1529
1530 void wxGnomePrintDC::DestroyClippingRegion()
1531 {
1532 }
1533
1534 bool wxGnomePrintDC::StartDoc(const wxString& message)
1535 {
1536 SetDeviceOrigin( 0,0 );
1537
1538 return true;
1539 }
1540
1541 void wxGnomePrintDC::EndDoc()
1542 {
1543 gs_lgp->gnome_print_end_doc( m_gpc );
1544 }
1545
1546 void wxGnomePrintDC::StartPage()
1547 {
1548 gs_lgp->gnome_print_beginpage( m_gpc, (const guchar*) "page" );
1549 }
1550
1551 void wxGnomePrintDC::EndPage()
1552 {
1553 gs_lgp->gnome_print_showpage( m_gpc );
1554 }
1555
1556 wxCoord wxGnomePrintDC::GetCharHeight() const
1557 {
1558 pango_layout_set_text( m_layout, "H", 1 );
1559
1560 int w,h;
1561 pango_layout_get_pixel_size( m_layout, &w, &h );
1562
1563 return h;
1564 }
1565
1566 wxCoord wxGnomePrintDC::GetCharWidth() const
1567 {
1568 pango_layout_set_text( m_layout, "H", 1 );
1569
1570 int w,h;
1571 pango_layout_get_pixel_size( m_layout, &w, &h );
1572
1573 return w;
1574 }
1575
1576 void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxCoord *height,
1577 wxCoord *descent,
1578 wxCoord *externalLeading,
1579 wxFont *theFont ) const
1580 {
1581 if ( width )
1582 *width = 0;
1583 if ( height )
1584 *height = 0;
1585 if ( descent )
1586 *descent = 0;
1587 if ( externalLeading )
1588 *externalLeading = 0;
1589
1590 if (string.IsEmpty())
1591 {
1592 return;
1593 }
1594
1595 // Set new font description
1596 if (theFont)
1597 pango_layout_set_font_description( m_layout, theFont->GetNativeFontInfo()->description );
1598
1599 // Set layout's text
1600 #if wxUSE_UNICODE
1601 const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
1602 const char *dataUTF8 = (const char *)data;
1603 #else
1604 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string );
1605 if ( !wdata )
1606 {
1607 if (width) (*width) = 0;
1608 if (height) (*height) = 0;
1609 return;
1610 }
1611 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1612 const char *dataUTF8 = (const char *)data;
1613 #endif
1614
1615 if ( !dataUTF8 )
1616 {
1617 // hardly ideal, but what else can we do if conversion failed?
1618 return;
1619 }
1620
1621 pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
1622
1623 int w,h;
1624 pango_layout_get_pixel_size( m_layout, &w, &h );
1625
1626 if (width)
1627 *width = (wxCoord)(w / m_scaleX);
1628 if (height)
1629 *height = (wxCoord)(h / m_scaleY);
1630 if (descent)
1631 {
1632 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
1633 int baseline = pango_layout_iter_get_baseline(iter);
1634 pango_layout_iter_free(iter);
1635 *descent = h - PANGO_PIXELS(baseline);
1636 }
1637
1638 // Reset old font description
1639 if (theFont)
1640 pango_layout_set_font_description( m_layout, m_fontdesc );
1641 }
1642
1643 void wxGnomePrintDC::DoGetSize(int* width, int* height) const
1644 {
1645 wxGnomePrintNativeData *native =
1646 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1647
1648 // Query page size. This seems to omit the margins
1649 // right now, although it shouldn't
1650 double pw,ph;
1651 gs_lgp->gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1652
1653 if (width)
1654 *width = (int) (pw + 0.5);
1655 if (height)
1656 *height = (int) (ph + 0.5);
1657 }
1658
1659 void wxGnomePrintDC::DoGetSizeMM(int *width, int *height) const
1660 {
1661 wxGnomePrintNativeData *native =
1662 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1663
1664 // This code assumes values in Pts.
1665
1666 double pw,ph;
1667 gs_lgp->gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1668
1669 // Convert to mm.
1670
1671 const GnomePrintUnit *mm_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "mm" );
1672 const GnomePrintUnit *pts_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "Pts" );
1673 gs_lgp->gnome_print_convert_distance( &pw, pts_unit, mm_unit );
1674 gs_lgp->gnome_print_convert_distance( &ph, pts_unit, mm_unit );
1675
1676 if (width)
1677 *width = (int) (pw + 0.5);
1678 if (height)
1679 *height = (int) (ph + 0.5);
1680 }
1681
1682 wxSize wxGnomePrintDC::GetPPI() const
1683 {
1684 return wxSize(72,72);
1685 }
1686
1687 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
1688 {
1689 m_signX = (xLeftRight ? 1 : -1);
1690 m_signY = (yBottomUp ? 1 : -1);
1691
1692 ComputeScaleAndOrigin();
1693 }
1694
1695 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x, wxCoord y )
1696 {
1697 int h = 0;
1698 int w = 0;
1699 GetSize( &w, &h );
1700
1701 wxDC::SetDeviceOrigin( x, h-y );
1702 }
1703
1704 void wxGnomePrintDC::SetResolution(int ppi)
1705 {
1706 }
1707
1708 int wxGnomePrintDC::GetResolution()
1709 {
1710 return 72;
1711 }
1712
1713
1714 class wxGnomePrintModule: public wxModule
1715 {
1716 public:
1717 wxGnomePrintModule() {}
1718 bool OnInit();
1719 void OnExit();
1720
1721 private:
1722 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule)
1723 };
1724
1725 bool wxGnomePrintModule::OnInit()
1726 {
1727 gs_lgp = new wxGnomePrintLibrary;
1728 if (gs_lgp->IsOk())
1729 wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory );
1730 return true;
1731 }
1732
1733 void wxGnomePrintModule::OnExit()
1734 {
1735 delete gs_lgp;
1736 }
1737
1738 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule, wxModule)
1739
1740 #endif
1741 // wxUSE_LIBGNOMEPRINT