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