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