]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/gnome/gprint.cpp
Disable wxUSE_ENH_METAFILE for wxGTK builds.
[wxWidgets.git] / src / gtk / gnome / gprint.cpp
... / ...
CommitLineData
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"
47wxFORCE_LINK_THIS_MODULE(gnome_print)
48
49//----------------------------------------------------------------------------
50// wxGnomePrintLibrary
51//----------------------------------------------------------------------------
52
53class wxGnomePrintLibrary
54{
55public:
56 wxGnomePrintLibrary();
57 ~wxGnomePrintLibrary();
58
59 bool IsOk();
60private:
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
71public:
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
191wxGnomePrintLibrary::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
211wxGnomePrintLibrary::~wxGnomePrintLibrary()
212{
213}
214
215bool wxGnomePrintLibrary::IsOk()
216{
217 return m_ok;
218}
219
220bool 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
289static wxGnomePrintLibrary* gs_libGnomePrint = NULL;
290
291//----------------------------------------------------------------------------
292// wxGnomePrintNativeData
293//----------------------------------------------------------------------------
294
295IMPLEMENT_CLASS(wxGnomePrintNativeData, wxPrintNativeDataBase)
296
297wxGnomePrintNativeData::wxGnomePrintNativeData()
298{
299 m_config = gs_libGnomePrint->gnome_print_config_default();
300 m_job = gs_libGnomePrint->gnome_print_job_new( m_config );
301}
302
303wxGnomePrintNativeData::~wxGnomePrintNativeData()
304{
305 g_object_unref (m_config);
306}
307
308bool 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
343bool 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
425wxPrinterBase* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData *data )
426{
427 return new wxGnomePrinter( data );
428}
429
430wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
431 wxPrintout *printout,
432 wxPrintDialogData *data )
433{
434 return new wxGnomePrintPreview( preview, printout, data );
435}
436
437wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
438 wxPrintout *printout,
439 wxPrintData *data )
440{
441 return new wxGnomePrintPreview( preview, printout, data );
442}
443
444wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
445 wxPrintDialogData *data )
446{
447 return new wxGnomePrintDialog( parent, data );
448}
449
450wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
451 wxPrintData *data )
452{
453 return new wxGnomePrintDialog( parent, data );
454}
455
456wxPageSetupDialogBase *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
469bool wxGnomePrintFactory::HasPrintSetupDialog()
470{
471 return false;
472}
473
474wxDialog *
475wxGnomePrintFactory::CreatePrintSetupDialog(wxWindow * WXUNUSED(parent),
476 wxPrintData * WXUNUSED(data))
477{
478 return NULL;
479}
480
481
482#if wxUSE_NEW_DC
483
484wxDCImpl* wxGnomePrintFactory::CreatePrinterDCImpl( wxPrinterDC *owner, const wxPrintData& data )
485{
486 return new wxGnomePrinterDCImpl( owner, data );
487}
488
489#else
490
491wxDC* wxGnomePrintFactory::CreatePrinterDC( const wxPrintData& data )
492{
493 return new wxGnomePrinterDC(data);
494}
495
496#endif
497
498bool wxGnomePrintFactory::HasOwnPrintToFile()
499{
500 return true;
501}
502
503bool wxGnomePrintFactory::HasPrinterLine()
504{
505 return true;
506}
507
508wxString wxGnomePrintFactory::CreatePrinterLine()
509{
510 // redundant now
511 return wxEmptyString;
512}
513
514bool wxGnomePrintFactory::HasStatusLine()
515{
516 // redundant now
517 return true;
518}
519
520wxString wxGnomePrintFactory::CreateStatusLine()
521{
522 // redundant now
523 return wxEmptyString;
524}
525
526wxPrintNativeDataBase *wxGnomePrintFactory::CreatePrintNativeData()
527{
528 return new wxGnomePrintNativeData;
529}
530
531//----------------------------------------------------------------------------
532// wxGnomePrintSetupDialog
533//----------------------------------------------------------------------------
534
535IMPLEMENT_CLASS(wxGnomePrintDialog, wxPrintDialogBase)
536
537wxGnomePrintDialog::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
549wxGnomePrintDialog::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
561void 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
588wxGnomePrintDialog::~wxGnomePrintDialog()
589{
590 m_widget = NULL;
591}
592
593int 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
645wxDC *wxGnomePrintDialog::GetPrintDC()
646{
647 // Later
648 return NULL;
649}
650
651bool wxGnomePrintDialog::Validate()
652{
653 return true;
654}
655
656bool wxGnomePrintDialog::TransferDataToWindow()
657{
658 return true;
659}
660
661bool wxGnomePrintDialog::TransferDataFromWindow()
662{
663 return true;
664}
665
666//----------------------------------------------------------------------------
667// wxGnomePageSetupDialog
668//----------------------------------------------------------------------------
669
670IMPLEMENT_CLASS(wxGnomePageSetupDialog, wxPageSetupDialogBase)
671
672wxGnomePageSetupDialog::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
731wxGnomePageSetupDialog::~wxGnomePageSetupDialog()
732{
733}
734
735wxPageSetupDialogData& wxGnomePageSetupDialog::GetPageSetupDialogData()
736{
737 return m_pageDialogData;
738}
739
740int 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
801bool wxGnomePageSetupDialog::Validate()
802{
803 return true;
804}
805
806bool wxGnomePageSetupDialog::TransferDataToWindow()
807{
808 return true;
809}
810
811bool wxGnomePageSetupDialog::TransferDataFromWindow()
812{
813 return true;
814}
815
816//----------------------------------------------------------------------------
817// wxGnomePrinter
818//----------------------------------------------------------------------------
819
820IMPLEMENT_CLASS(wxGnomePrinter, wxPrinterBase)
821
822wxGnomePrinter::wxGnomePrinter( wxPrintDialogData *data ) :
823 wxPrinterBase( data )
824{
825 m_native_preview = false;
826}
827
828wxGnomePrinter::~wxGnomePrinter()
829{
830}
831
832bool 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
964wxDC* 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
984bool wxGnomePrinter::Setup(wxWindow * WXUNUSED(parent))
985{
986 return false;
987}
988
989//-----------------------------------------------------------------------------
990// wxGnomePrinterDC
991//-----------------------------------------------------------------------------
992
993// conversion
994static const double RAD2DEG = 180.0 / M_PI;
995
996// we don't want to use only 72 dpi from GNOME print
997static const int DPI = 600;
998static const double PS2DEV = 600.0 / 72.0;
999static 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
1007IMPLEMENT_ABSTRACT_CLASS(wxGnomePrinterDCImpl, wxDCImpl)
1008#else
1009IMPLEMENT_ABSTRACT_CLASS(wxGnomePrinterDC, wxDC)
1010#endif
1011
1012#if wxUSE_NEW_DC
1013wxGnomePrinterDCImpl::wxGnomePrinterDCImpl( wxPrinterDC *owner, const wxPrintData& data ) :
1014 wxDCImpl( owner )
1015#else
1016wxGnomePrinterDC::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
1042wxGnomePrinterDCImpl::~wxGnomePrinterDCImpl()
1043{
1044}
1045
1046bool wxGnomePrinterDCImpl::IsOk() const
1047{
1048 return true;
1049}
1050
1051bool
1052wxGnomePrinterDCImpl::DoFloodFill(wxCoord WXUNUSED(x1),
1053 wxCoord WXUNUSED(y1),
1054 const wxColour& WXUNUSED(col),
1055 wxFloodFillStyle WXUNUSED(style))
1056{
1057 return false;
1058}
1059
1060bool
1061wxGnomePrinterDCImpl::DoGetPixel(wxCoord WXUNUSED(x1),
1062 wxCoord WXUNUSED(y1),
1063 wxColour * WXUNUSED(col)) const
1064{
1065 return false;
1066}
1067
1068void 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
1083void wxGnomePrinterDCImpl::DoCrossHair(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
1084{
1085}
1086
1087void 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
1143void 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
1188void wxGnomePrinterDCImpl::DoDrawPoint(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
1189{
1190}
1191
1192void 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
1213void 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
1261void 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
1270void 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
1308void 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
1380void 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
1426void 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
1451void 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
1510bool
1511wxGnomePrinterDCImpl::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
1534void wxGnomePrinterDCImpl::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
1535{
1536 DoDrawBitmap( icon, x, y, true );
1537}
1538
1539void
1540wxGnomePrinterDCImpl::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
1592void wxGnomePrinterDCImpl::DoDrawText(const wxString& text, wxCoord x, wxCoord y )
1593{
1594 DoDrawRotatedText( text, x, y, 0.0 );
1595}
1596
1597void 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
1663void wxGnomePrinterDCImpl::Clear()
1664{
1665}
1666
1667void 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
1686void 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
1752void 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
1791void wxGnomePrinterDCImpl::SetLogicalFunction(wxRasterOperationMode WXUNUSED(function))
1792{
1793}
1794
1795void wxGnomePrinterDCImpl::SetBackground(const wxBrush& WXUNUSED(brush))
1796{
1797}
1798
1799void 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
1822void 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
1841bool wxGnomePrinterDCImpl::StartDoc(const wxString& WXUNUSED(message))
1842{
1843 return true;
1844}
1845
1846void wxGnomePrinterDCImpl::EndDoc()
1847{
1848 gs_libGnomePrint->gnome_print_end_doc( m_gpc );
1849}
1850
1851void wxGnomePrinterDCImpl::StartPage()
1852{
1853 gs_libGnomePrint->gnome_print_beginpage( m_gpc, (const guchar*) "page" );
1854}
1855
1856void wxGnomePrinterDCImpl::EndPage()
1857{
1858 gs_libGnomePrint->gnome_print_showpage( m_gpc );
1859}
1860
1861wxCoord 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
1871wxCoord 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
1881void 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
1941void 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
1957void 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
1980wxSize wxGnomePrinterDCImpl::GetPPI() const
1981{
1982 return wxSize(DPI,DPI);
1983}
1984
1985void 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
1999int wxGnomePrinterDCImpl::GetResolution() const
2000{
2001 return DPI;
2002}
2003
2004wxRect 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
2017bool wxGnomePrintModule::OnInit()
2018{
2019 gs_libGnomePrint = new wxGnomePrintLibrary;
2020 if (gs_libGnomePrint->IsOk())
2021 wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory );
2022 return true;
2023}
2024
2025void wxGnomePrintModule::OnExit()
2026{
2027 wxDELETE(gs_libGnomePrint);
2028}
2029
2030IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule, wxModule)
2031
2032// ----------------------------------------------------------------------------
2033// Print preview
2034// ----------------------------------------------------------------------------
2035
2036IMPLEMENT_CLASS(wxGnomePrintPreview, wxPrintPreviewBase)
2037
2038void wxGnomePrintPreview::Init(wxPrintout * WXUNUSED(printout),
2039 wxPrintout * WXUNUSED(printoutForPrinting))
2040{
2041 DetermineScaling();
2042}
2043
2044wxGnomePrintPreview::wxGnomePrintPreview(wxPrintout *printout,
2045 wxPrintout *printoutForPrinting,
2046 wxPrintDialogData *data)
2047 : wxPrintPreviewBase(printout, printoutForPrinting, data)
2048{
2049 Init(printout, printoutForPrinting);
2050}
2051
2052wxGnomePrintPreview::wxGnomePrintPreview(wxPrintout *printout,
2053 wxPrintout *printoutForPrinting,
2054 wxPrintData *data)
2055 : wxPrintPreviewBase(printout, printoutForPrinting, data)
2056{
2057 Init(printout, printoutForPrinting);
2058}
2059
2060wxGnomePrintPreview::~wxGnomePrintPreview()
2061{
2062}
2063
2064bool 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
2073void 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