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