]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/gnome/gprint.cpp
Implement DrawEllipticArc for GNOME print.
[wxWidgets.git] / src / gtk / 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 }
1165
1166 bool wxGnomePrintDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
1167 wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
1168 wxCoord xsrcMask, wxCoord ysrcMask)
1169 {
1170 return false;
1171 }
1172
1173 void wxGnomePrintDC::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
1174 {
1175 DoDrawBitmap( icon, x, y, true );
1176 }
1177
1178 void wxGnomePrintDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool useMask )
1179 {
1180 if (!bitmap.Ok()) return;
1181
1182 if (bitmap.HasPixbuf())
1183 {
1184 GdkPixbuf *pixbuf = bitmap.GetPixbuf();
1185 guchar *raw_image = gdk_pixbuf_get_pixels( pixbuf );
1186 bool has_alpha = gdk_pixbuf_get_has_alpha( pixbuf );
1187 int rowstride = gdk_pixbuf_get_rowstride( pixbuf );
1188 int height = gdk_pixbuf_get_height( pixbuf );
1189 int width = gdk_pixbuf_get_width( pixbuf );
1190
1191 gs_lgp->gnome_print_gsave( m_gpc );
1192 double matrix[6];
1193 matrix[0] = XLOG2DEVREL(width);
1194 matrix[1] = 0;
1195 matrix[2] = 0;
1196 matrix[3] = YLOG2DEVREL(height);
1197 matrix[4] = XLOG2DEV(x);
1198 matrix[5] = YLOG2DEV(y+height);
1199 gs_lgp->gnome_print_concat( m_gpc, matrix );
1200 gs_lgp->gnome_print_moveto( m_gpc, 0, 0 );
1201 if (has_alpha)
1202 gs_lgp->gnome_print_rgbaimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
1203 else
1204 gs_lgp->gnome_print_rgbimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
1205 gs_lgp->gnome_print_grestore( m_gpc );
1206 }
1207 else
1208 {
1209 wxImage image = bitmap.ConvertToImage();
1210
1211 if (!image.Ok()) return;
1212
1213 gs_lgp->gnome_print_gsave( m_gpc );
1214 double matrix[6];
1215 matrix[0] = XLOG2DEVREL(image.GetWidth());
1216 matrix[1] = 0;
1217 matrix[2] = 0;
1218 matrix[3] = YLOG2DEVREL(image.GetHeight());
1219 matrix[4] = XLOG2DEV(x);
1220 matrix[5] = YLOG2DEV(y+image.GetHeight());
1221 gs_lgp->gnome_print_concat( m_gpc, matrix );
1222 gs_lgp->gnome_print_moveto( m_gpc, 0, 0 );
1223 gs_lgp->gnome_print_rgbimage( m_gpc, (guchar*) image.GetData(), image.GetWidth(), image.GetHeight(), image.GetWidth()*3 );
1224 gs_lgp->gnome_print_grestore( m_gpc );
1225 }
1226 }
1227
1228 void wxGnomePrintDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y )
1229 {
1230 DoDrawRotatedText( text, x, y, 0.0 );
1231 }
1232
1233 void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
1234 {
1235 x = XLOG2DEV(x);
1236 y = YLOG2DEV(y);
1237
1238 bool underlined = m_font.Ok() && m_font.GetUnderlined();
1239
1240 #if wxUSE_UNICODE
1241 const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
1242 #else
1243 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text );
1244 if ( !wdata )
1245 return;
1246 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1247 #endif
1248
1249 size_t datalen = strlen((const char*)data);
1250 pango_layout_set_text( m_layout, (const char*) data, datalen);
1251
1252 if (underlined)
1253 {
1254 PangoAttrList *attrs = pango_attr_list_new();
1255 PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
1256 a->start_index = 0;
1257 a->end_index = datalen;
1258 pango_attr_list_insert(attrs, a);
1259 pango_layout_set_attributes(m_layout, attrs);
1260 pango_attr_list_unref(attrs);
1261 }
1262
1263 if (m_textForegroundColour.Ok())
1264 {
1265 unsigned char red = m_textForegroundColour.Red();
1266 unsigned char blue = m_textForegroundColour.Blue();
1267 unsigned char green = m_textForegroundColour.Green();
1268
1269 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1270 {
1271 double redPS = (double)(red) / 255.0;
1272 double bluePS = (double)(blue) / 255.0;
1273 double greenPS = (double)(green) / 255.0;
1274
1275 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1276
1277 m_currentRed = red;
1278 m_currentBlue = blue;
1279 m_currentGreen = green;
1280 }
1281 }
1282
1283 int w,h;
1284
1285 if (fabs(m_scaleY - 1.0) > 0.00001)
1286 {
1287 // If there is a user or actually any scale applied to
1288 // the device context, scale the font.
1289
1290 // scale font description
1291 gint oldSize = pango_font_description_get_size( m_fontdesc );
1292 double size = oldSize;
1293 size = size * m_scaleY;
1294 pango_font_description_set_size( m_fontdesc, (gint)size );
1295
1296 // actually apply scaled font
1297 pango_layout_set_font_description( m_layout, m_fontdesc );
1298
1299 pango_layout_get_pixel_size( m_layout, &w, &h );
1300 #if 0
1301 if ( m_backgroundMode == wxSOLID )
1302 {
1303 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1304 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
1305 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1306 }
1307 #endif
1308 // Draw layout.
1309 gs_lgp->gnome_print_moveto (m_gpc, x, y);
1310 if (fabs(angle) > 0.00001)
1311 {
1312 gs_lgp->gnome_print_gsave( m_gpc );
1313 gs_lgp->gnome_print_rotate( m_gpc, angle );
1314 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1315 gs_lgp->gnome_print_grestore( m_gpc );
1316 }
1317 else
1318 {
1319 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1320 }
1321
1322 // reset unscaled size
1323 pango_font_description_set_size( m_fontdesc, oldSize );
1324
1325 // actually apply unscaled font
1326 pango_layout_set_font_description( m_layout, m_fontdesc );
1327 }
1328 else
1329 {
1330 pango_layout_get_pixel_size( m_layout, &w, &h );
1331 #if 0
1332 if ( m_backgroundMode == wxSOLID )
1333 {
1334 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1335 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
1336 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1337 }
1338 #endif
1339 // Draw layout.
1340 gs_lgp->gnome_print_moveto (m_gpc, x, y);
1341 if (fabs(angle) > 0.00001)
1342 {
1343 gs_lgp->gnome_print_gsave( m_gpc );
1344 gs_lgp->gnome_print_rotate( m_gpc, angle );
1345 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1346 gs_lgp->gnome_print_grestore( m_gpc );
1347 }
1348 else
1349 {
1350 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1351 }
1352 }
1353
1354 if (underlined)
1355 {
1356 // undo underline attributes setting:
1357 pango_layout_set_attributes(m_layout, NULL);
1358 }
1359
1360 CalcBoundingBox (x + w, y + h);
1361 }
1362
1363 void wxGnomePrintDC::Clear()
1364 {
1365 }
1366
1367 void wxGnomePrintDC::SetFont( const wxFont& font )
1368 {
1369 m_font = font;
1370
1371 if (m_font.Ok())
1372 {
1373 if (m_fontdesc)
1374 pango_font_description_free( m_fontdesc );
1375
1376 m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description );
1377
1378 pango_layout_set_font_description( m_layout, m_fontdesc );
1379 }
1380 }
1381
1382 void wxGnomePrintDC::SetPen( const wxPen& pen )
1383 {
1384 if (!pen.Ok()) return;
1385
1386 m_pen = pen;
1387
1388 gs_lgp->gnome_print_setlinewidth( m_gpc, XLOG2DEVREL( 1000 * m_pen.GetWidth() ) / 1000.0f );
1389
1390 static const double dotted[] = {2.0, 5.0};
1391 static const double short_dashed[] = {4.0, 4.0};
1392 static const double wxCoord_dashed[] = {4.0, 8.0};
1393 static const double dotted_dashed[] = {6.0, 6.0, 2.0, 6.0};
1394
1395 switch (m_pen.GetStyle())
1396 {
1397 case wxDOT: gs_lgp->gnome_print_setdash( m_gpc, 2, dotted, 0 ); break;
1398 case wxSHORT_DASH: gs_lgp->gnome_print_setdash( m_gpc, 2, short_dashed, 0 ); break;
1399 case wxLONG_DASH: gs_lgp->gnome_print_setdash( m_gpc, 2, wxCoord_dashed, 0 ); break;
1400 case wxDOT_DASH: gs_lgp->gnome_print_setdash( m_gpc, 4, dotted_dashed, 0 ); break;
1401 case wxSOLID:
1402 case wxTRANSPARENT:
1403 default: gs_lgp->gnome_print_setdash( m_gpc, 0, NULL, 0 ); break;
1404 }
1405
1406
1407 unsigned char red = m_pen.GetColour().Red();
1408 unsigned char blue = m_pen.GetColour().Blue();
1409 unsigned char green = m_pen.GetColour().Green();
1410
1411 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1412 {
1413 double redPS = (double)(red) / 255.0;
1414 double bluePS = (double)(blue) / 255.0;
1415 double greenPS = (double)(green) / 255.0;
1416
1417 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1418
1419 m_currentRed = red;
1420 m_currentBlue = blue;
1421 m_currentGreen = green;
1422 }
1423 }
1424
1425 void wxGnomePrintDC::SetBrush( const wxBrush& brush )
1426 {
1427 if (!brush.Ok()) return;
1428
1429 m_brush = brush;
1430
1431 // Brush colour
1432 unsigned char red = m_brush.GetColour().Red();
1433 unsigned char blue = m_brush.GetColour().Blue();
1434 unsigned char green = m_brush.GetColour().Green();
1435
1436 if (!m_colour)
1437 {
1438 // Anything not white is black
1439 if (! (red == (unsigned char) 255 &&
1440 blue == (unsigned char) 255 &&
1441 green == (unsigned char) 255) )
1442 {
1443 red = (unsigned char) 0;
1444 green = (unsigned char) 0;
1445 blue = (unsigned char) 0;
1446 }
1447 // setgray here ?
1448 }
1449
1450 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1451 {
1452 double redPS = (double)(red) / 255.0;
1453 double bluePS = (double)(blue) / 255.0;
1454 double greenPS = (double)(green) / 255.0;
1455
1456 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1457
1458 m_currentRed = red;
1459 m_currentBlue = blue;
1460 m_currentGreen = green;
1461 }
1462 }
1463
1464 void wxGnomePrintDC::SetLogicalFunction( int function )
1465 {
1466 }
1467
1468 void wxGnomePrintDC::SetBackground( const wxBrush& brush )
1469 {
1470 }
1471
1472 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
1473 {
1474 }
1475
1476 void wxGnomePrintDC::DestroyClippingRegion()
1477 {
1478 }
1479
1480 bool wxGnomePrintDC::StartDoc(const wxString& message)
1481 {
1482 SetDeviceOrigin( 0,0 );
1483
1484 return true;
1485 }
1486
1487 void wxGnomePrintDC::EndDoc()
1488 {
1489 gs_lgp->gnome_print_end_doc( m_gpc );
1490 }
1491
1492 void wxGnomePrintDC::StartPage()
1493 {
1494 gs_lgp->gnome_print_beginpage( m_gpc, (const guchar*) "page" );
1495 }
1496
1497 void wxGnomePrintDC::EndPage()
1498 {
1499 gs_lgp->gnome_print_showpage( m_gpc );
1500 }
1501
1502 wxCoord wxGnomePrintDC::GetCharHeight() const
1503 {
1504 pango_layout_set_text( m_layout, "H", 1 );
1505
1506 int w,h;
1507 pango_layout_get_pixel_size( m_layout, &w, &h );
1508
1509 return h;
1510 }
1511
1512 wxCoord wxGnomePrintDC::GetCharWidth() const
1513 {
1514 pango_layout_set_text( m_layout, "H", 1 );
1515
1516 int w,h;
1517 pango_layout_get_pixel_size( m_layout, &w, &h );
1518
1519 return w;
1520 }
1521
1522 void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxCoord *height,
1523 wxCoord *descent,
1524 wxCoord *externalLeading,
1525 wxFont *theFont ) const
1526 {
1527 if ( width )
1528 *width = 0;
1529 if ( height )
1530 *height = 0;
1531 if ( descent )
1532 *descent = 0;
1533 if ( externalLeading )
1534 *externalLeading = 0;
1535
1536 if (string.IsEmpty())
1537 {
1538 return;
1539 }
1540
1541 // Set new font description
1542 if (theFont)
1543 pango_layout_set_font_description( m_layout, theFont->GetNativeFontInfo()->description );
1544
1545 // Set layout's text
1546 #if wxUSE_UNICODE
1547 const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
1548 const char *dataUTF8 = (const char *)data;
1549 #else
1550 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string );
1551 if ( !wdata )
1552 {
1553 if (width) (*width) = 0;
1554 if (height) (*height) = 0;
1555 return;
1556 }
1557 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1558 const char *dataUTF8 = (const char *)data;
1559 #endif
1560
1561 if ( !dataUTF8 )
1562 {
1563 // hardly ideal, but what else can we do if conversion failed?
1564 return;
1565 }
1566
1567 pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
1568
1569 int w,h;
1570 pango_layout_get_pixel_size( m_layout, &w, &h );
1571
1572 if (width)
1573 *width = (wxCoord)(w / m_scaleX);
1574 if (height)
1575 *height = (wxCoord)(h / m_scaleY);
1576 if (descent)
1577 {
1578 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
1579 int baseline = pango_layout_iter_get_baseline(iter);
1580 pango_layout_iter_free(iter);
1581 *descent = h - PANGO_PIXELS(baseline);
1582 }
1583
1584 // Reset old font description
1585 if (theFont)
1586 pango_layout_set_font_description( m_layout, m_fontdesc );
1587 }
1588
1589 void wxGnomePrintDC::DoGetSize(int* width, int* height) const
1590 {
1591 wxGnomePrintNativeData *native =
1592 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1593
1594 // Query page size. This seems to omit the margins
1595 // right now, although it shouldn't
1596 double pw,ph;
1597 gs_lgp->gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1598
1599 if (width)
1600 *width = (int) (pw + 0.5);
1601 if (height)
1602 *height = (int) (ph + 0.5);
1603 }
1604
1605 void wxGnomePrintDC::DoGetSizeMM(int *width, int *height) const
1606 {
1607 wxGnomePrintNativeData *native =
1608 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1609
1610 // This code assumes values in Pts.
1611
1612 double pw,ph;
1613 gs_lgp->gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1614
1615 // Convert to mm.
1616
1617 const GnomePrintUnit *mm_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "mm" );
1618 const GnomePrintUnit *pts_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "Pts" );
1619 gs_lgp->gnome_print_convert_distance( &pw, pts_unit, mm_unit );
1620 gs_lgp->gnome_print_convert_distance( &ph, pts_unit, mm_unit );
1621
1622 if (width)
1623 *width = (int) (pw + 0.5);
1624 if (height)
1625 *height = (int) (ph + 0.5);
1626 }
1627
1628 wxSize wxGnomePrintDC::GetPPI() const
1629 {
1630 return wxSize(72,72);
1631 }
1632
1633 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
1634 {
1635 m_signX = (xLeftRight ? 1 : -1);
1636 m_signY = (yBottomUp ? 1 : -1);
1637
1638 ComputeScaleAndOrigin();
1639 }
1640
1641 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x, wxCoord y )
1642 {
1643 int h = 0;
1644 int w = 0;
1645 GetSize( &w, &h );
1646
1647 wxDC::SetDeviceOrigin( x, h-y );
1648 }
1649
1650 void wxGnomePrintDC::SetResolution(int ppi)
1651 {
1652 }
1653
1654 int wxGnomePrintDC::GetResolution()
1655 {
1656 return 72;
1657 }
1658
1659
1660 class wxGnomePrintModule: public wxModule
1661 {
1662 public:
1663 wxGnomePrintModule() {}
1664 bool OnInit();
1665 void OnExit();
1666
1667 private:
1668 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule)
1669 };
1670
1671 bool wxGnomePrintModule::OnInit()
1672 {
1673 gs_lgp = new wxGnomePrintLibrary;
1674 if (gs_lgp->IsOk())
1675 wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory );
1676 return true;
1677 }
1678
1679 void wxGnomePrintModule::OnExit()
1680 {
1681 delete gs_lgp;
1682 }
1683
1684 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule, wxModule)
1685
1686 #endif
1687 // wxUSE_LIBGNOMEPRINT