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