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: gprint.cpp 59294 2009-03-03 10:34:35Z VZ $
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
wxGnomePrintLibrary()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
~wxGnomePrintLibrary()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
IsOk()220 bool wxGnomePrintLibrary::IsOk()
221 {
222 return m_ok;
223 }
224
InitializeMethods()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
IMPLEMENT_CLASS(wxGnomePrintNativeData,wxPrintNativeDataBase)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
~wxGnomePrintNativeData()310 wxGnomePrintNativeData::~wxGnomePrintNativeData()
311 {
312 g_object_unref (m_config);
313 }
314
TransferTo(wxPrintData & data)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
TransferFrom(const wxPrintData & data)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
CreatePrinter(wxPrintDialogData * data)410 wxPrinterBase* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData *data )
411 {
412 return new wxGnomePrinter( data );
413 }
414
CreatePrintPreview(wxPrintout * preview,wxPrintout * printout,wxPrintDialogData * data)415 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
416 wxPrintout *printout,
417 wxPrintDialogData *data )
418 {
419 return new wxGnomePrintPreview( preview, printout, data );
420 }
421
CreatePrintPreview(wxPrintout * preview,wxPrintout * printout,wxPrintData * data)422 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
423 wxPrintout *printout,
424 wxPrintData *data )
425 {
426 return new wxGnomePrintPreview( preview, printout, data );
427 }
428
CreatePrintDialog(wxWindow * parent,wxPrintDialogData * data)429 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
430 wxPrintDialogData *data )
431 {
432 return new wxGnomePrintDialog( parent, data );
433 }
434
CreatePrintDialog(wxWindow * parent,wxPrintData * data)435 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
436 wxPrintData *data )
437 {
438 return new wxGnomePrintDialog( parent, data );
439 }
440
CreatePageSetupDialog(wxWindow * parent,wxPageSetupDialogData * data)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
HasPrintSetupDialog()454 bool wxGnomePrintFactory::HasPrintSetupDialog()
455 {
456 return false;
457 }
458
CreatePrintSetupDialog(wxWindow * parent,wxPrintData * data)459 wxDialog *wxGnomePrintFactory::CreatePrintSetupDialog( wxWindow *parent, wxPrintData *data )
460 {
461 return NULL;
462 }
463
CreatePrinterDC(const wxPrintData & data)464 wxDC* wxGnomePrintFactory::CreatePrinterDC( const wxPrintData& data )
465 {
466 return new wxGnomePrintDC(data);
467 }
468
HasOwnPrintToFile()469 bool wxGnomePrintFactory::HasOwnPrintToFile()
470 {
471 return true;
472 }
473
HasPrinterLine()474 bool wxGnomePrintFactory::HasPrinterLine()
475 {
476 return true;
477 }
478
CreatePrinterLine()479 wxString wxGnomePrintFactory::CreatePrinterLine()
480 {
481 // redundant now
482 return wxEmptyString;
483 }
484
HasStatusLine()485 bool wxGnomePrintFactory::HasStatusLine()
486 {
487 // redundant now
488 return true;
489 }
490
CreateStatusLine()491 wxString wxGnomePrintFactory::CreateStatusLine()
492 {
493 // redundant now
494 return wxEmptyString;
495 }
496
CreatePrintNativeData()497 wxPrintNativeDataBase *wxGnomePrintFactory::CreatePrintNativeData()
498 {
499 return new wxGnomePrintNativeData;
500 }
501
502 //----------------------------------------------------------------------------
503 // wxGnomePrintSetupDialog
504 //----------------------------------------------------------------------------
505
IMPLEMENT_CLASS(wxGnomePrintDialog,wxPrintDialogBase)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
wxGnomePrintDialog(wxWindow * parent,wxPrintData * data)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
Init()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
~wxGnomePrintDialog()559 wxGnomePrintDialog::~wxGnomePrintDialog()
560 {
561 m_widget = NULL;
562 }
563
ShowModal()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
GetPrintDC()612 wxDC *wxGnomePrintDialog::GetPrintDC()
613 {
614 // Later
615 return NULL;
616 }
617
Validate()618 bool wxGnomePrintDialog::Validate()
619 {
620 return true;
621 }
622
TransferDataToWindow()623 bool wxGnomePrintDialog::TransferDataToWindow()
624 {
625 return true;
626 }
627
TransferDataFromWindow()628 bool wxGnomePrintDialog::TransferDataFromWindow()
629 {
630 return true;
631 }
632
633 //----------------------------------------------------------------------------
634 // wxGnomePageSetupDialog
635 //----------------------------------------------------------------------------
636
IMPLEMENT_CLASS(wxGnomePageSetupDialog,wxPageSetupDialogBase)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
~wxGnomePageSetupDialog()698 wxGnomePageSetupDialog::~wxGnomePageSetupDialog()
699 {
700 }
701
GetPageSetupDialogData()702 wxPageSetupDialogData& wxGnomePageSetupDialog::GetPageSetupDialogData()
703 {
704 return m_pageDialogData;
705 }
706
ShowModal()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
Validate()766 bool wxGnomePageSetupDialog::Validate()
767 {
768 return true;
769 }
770
TransferDataToWindow()771 bool wxGnomePageSetupDialog::TransferDataToWindow()
772 {
773 return true;
774 }
775
TransferDataFromWindow()776 bool wxGnomePageSetupDialog::TransferDataFromWindow()
777 {
778 return true;
779 }
780
781 //----------------------------------------------------------------------------
782 // wxGnomePrinter
783 //----------------------------------------------------------------------------
784
IMPLEMENT_CLASS(wxGnomePrinter,wxPrinterBase)785 IMPLEMENT_CLASS(wxGnomePrinter, wxPrinterBase)
786
787 wxGnomePrinter::wxGnomePrinter( wxPrintDialogData *data ) :
788 wxPrinterBase( data )
789 {
790 m_native_preview = false;
791 }
792
~wxGnomePrinter()793 wxGnomePrinter::~wxGnomePrinter()
794 {
795 }
796
Print(wxWindow * parent,wxPrintout * printout,bool prompt)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
PrintDialog(wxWindow * parent)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
Setup(wxWindow * parent)950 bool wxGnomePrinter::Setup( wxWindow *parent )
951 {
952 return false;
953 }
954
955 //-----------------------------------------------------------------------------
956 // wxGnomePrintDC
957 //-----------------------------------------------------------------------------
958
IMPLEMENT_CLASS(wxGnomePrintDC,wxDC)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
~wxGnomePrintDC()985 wxGnomePrintDC::~wxGnomePrintDC()
986 {
987 }
988
IsOk() const989 bool wxGnomePrintDC::IsOk() const
990 {
991 return true;
992 }
993
DoFloodFill(wxCoord x1,wxCoord y1,const wxColour & col,int style)994 bool wxGnomePrintDC::DoFloodFill(wxCoord x1, wxCoord y1, const wxColour &col, int style )
995 {
996 return false;
997 }
998
DoGetPixel(wxCoord x1,wxCoord y1,wxColour * col) const999 bool wxGnomePrintDC::DoGetPixel(wxCoord x1, wxCoord y1, wxColour *col) const
1000 {
1001 return false;
1002 }
1003
DoDrawLine(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2)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
DoCrossHair(wxCoord x,wxCoord y)1018 void wxGnomePrintDC::DoCrossHair(wxCoord x, wxCoord y)
1019 {
1020 }
1021
DoDrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2,wxCoord xc,wxCoord yc)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
DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)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
DoDrawPoint(wxCoord x,wxCoord y)1123 void wxGnomePrintDC::DoDrawPoint(wxCoord x, wxCoord y)
1124 {
1125 }
1126
DoDrawLines(int n,wxPoint points[],wxCoord xoffset,wxCoord yoffset)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
DoDrawPolygon(int n,wxPoint points[],wxCoord xoffset,wxCoord yoffset,int fillStyle)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
DoDrawPolyPolygon(int n,int count[],wxPoint points[],wxCoord xoffset,wxCoord yoffset,int fillStyle)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
DoDrawRectangle(wxCoord x,wxCoord y,wxCoord width,wxCoord height)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
DoDrawRoundedRectangle(wxCoord x,wxCoord y,wxCoord width,wxCoord height,double radius)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
makeEllipticalPath(wxCoord x,wxCoord y,wxCoord width,wxCoord height)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
DoDrawEllipse(wxCoord x,wxCoord y,wxCoord width,wxCoord height)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
DoDrawSpline(wxList * points)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
DoBlit(wxCoord xdest,wxCoord ydest,wxCoord width,wxCoord height,wxDC * source,wxCoord xsrc,wxCoord ysrc,int rop,bool useMask,wxCoord xsrcMask,wxCoord ysrcMask)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
DoDrawIcon(const wxIcon & icon,wxCoord x,wxCoord y)1448 void wxGnomePrintDC::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
1449 {
1450 DoDrawBitmap( icon, x, y, true );
1451 }
1452
DoDrawBitmap(const wxBitmap & bitmap,wxCoord x,wxCoord y,bool useMask)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
DoDrawText(const wxString & text,wxCoord x,wxCoord y)1503 void wxGnomePrintDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y )
1504 {
1505 DoDrawRotatedText( text, x, y, 0.0 );
1506 }
1507
DoDrawRotatedText(const wxString & text,wxCoord x,wxCoord y,double angle)1508 void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
1509 {
1510 double xx = XLOG2DEV(x);
1511 double yy = YLOG2DEV(y);
1512
1513 bool underlined = m_font.Ok() && m_font.GetUnderlined();
1514
1515 #if wxUSE_UNICODE
1516 const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
1517 #else
1518 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text );
1519 if ( !wdata )
1520 return;
1521 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1522 #endif
1523
1524 size_t datalen = strlen((const char*)data);
1525 pango_layout_set_text( m_layout, (const char*) data, datalen);
1526
1527 if (underlined)
1528 {
1529 PangoAttrList *attrs = pango_attr_list_new();
1530 PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
1531 a->start_index = 0;
1532 a->end_index = datalen;
1533 pango_attr_list_insert(attrs, a);
1534 pango_layout_set_attributes(m_layout, attrs);
1535 pango_attr_list_unref(attrs);
1536 }
1537
1538 if (m_textForegroundColour.Ok())
1539 {
1540 unsigned char red = m_textForegroundColour.Red();
1541 unsigned char blue = m_textForegroundColour.Blue();
1542 unsigned char green = m_textForegroundColour.Green();
1543
1544 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1545 {
1546 double redPS = (double)(red) / 255.0;
1547 double bluePS = (double)(blue) / 255.0;
1548 double greenPS = (double)(green) / 255.0;
1549
1550 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1551
1552 m_currentRed = red;
1553 m_currentBlue = blue;
1554 m_currentGreen = green;
1555 }
1556 }
1557
1558 #if 0
1559 if ( m_backgroundMode == wxSOLID )
1560 {
1561 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
1562 gdk_draw_rectangle(m_window, m_textGC, TRUE, xx, yy, w, h);
1563 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
1564 }
1565 #endif
1566
1567 // Draw layout.
1568 gs_lgp->gnome_print_moveto (m_gpc, xx, yy);
1569
1570 gs_lgp->gnome_print_gsave( m_gpc );
1571
1572 gs_lgp->gnome_print_scale( m_gpc, m_scaleX, m_scaleY );
1573
1574 if (fabs(angle) > 0.00001)
1575 gs_lgp->gnome_print_rotate( m_gpc, angle );
1576
1577 gs_lgp->gnome_print_pango_layout( m_gpc, m_layout );
1578
1579 int w,h;
1580 pango_layout_get_pixel_size( m_layout, &w, &h );
1581
1582 gs_lgp->gnome_print_grestore( m_gpc );
1583
1584 if (underlined)
1585 {
1586 // undo underline attributes setting:
1587 pango_layout_set_attributes(m_layout, NULL);
1588 }
1589
1590 CalcBoundingBox(x, y);
1591 CalcBoundingBox(x + w, y + h);
1592 }
1593
Clear()1594 void wxGnomePrintDC::Clear()
1595 {
1596 }
1597
SetFont(const wxFont & font)1598 void wxGnomePrintDC::SetFont( const wxFont& font )
1599 {
1600 m_font = font;
1601
1602 if (m_font.Ok())
1603 {
1604 if (m_fontdesc)
1605 pango_font_description_free( m_fontdesc );
1606
1607 m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description );
1608
1609 float size = pango_font_description_get_size( m_fontdesc );
1610 size = size * GetFontPointSizeAdjustment(72.0);
1611 pango_font_description_set_size( m_fontdesc, (gint)size );
1612
1613 pango_layout_set_font_description( m_layout, m_fontdesc );
1614 }
1615 }
1616
SetPen(const wxPen & pen)1617 void wxGnomePrintDC::SetPen( const wxPen& pen )
1618 {
1619 if (!pen.Ok()) return;
1620
1621 m_pen = pen;
1622
1623 gs_lgp->gnome_print_setlinewidth( m_gpc, XLOG2DEVREL( 1000 * m_pen.GetWidth() ) / 1000.0f );
1624
1625 static const double dotted[] = {2.0, 5.0};
1626 static const double short_dashed[] = {4.0, 4.0};
1627 static const double wxCoord_dashed[] = {4.0, 8.0};
1628 static const double dotted_dashed[] = {6.0, 6.0, 2.0, 6.0};
1629
1630 switch (m_pen.GetStyle())
1631 {
1632 case wxDOT: gs_lgp->gnome_print_setdash( m_gpc, 2, dotted, 0 ); break;
1633 case wxSHORT_DASH: gs_lgp->gnome_print_setdash( m_gpc, 2, short_dashed, 0 ); break;
1634 case wxLONG_DASH: gs_lgp->gnome_print_setdash( m_gpc, 2, wxCoord_dashed, 0 ); break;
1635 case wxDOT_DASH: gs_lgp->gnome_print_setdash( m_gpc, 4, dotted_dashed, 0 ); break;
1636 case wxUSER_DASH:
1637 {
1638 // It may be noted that libgnomeprint between at least
1639 // versions 2.8.0 and 2.12.1 makes a copy of the dashes
1640 // and then leak the memory since it doesn't set the
1641 // internal flag "privatedash" to 0.
1642 wxDash *wx_dashes;
1643 int num = m_pen.GetDashes (&wx_dashes);
1644 gdouble *g_dashes = g_new( gdouble, num );
1645 int i;
1646 for (i = 0; i < num; ++i)
1647 g_dashes[i] = (gdouble) wx_dashes[i];
1648 gs_lgp -> gnome_print_setdash( m_gpc, num, g_dashes, 0);
1649 g_free( g_dashes );
1650 }
1651 break;
1652 case wxSOLID:
1653 case wxTRANSPARENT:
1654 default: gs_lgp->gnome_print_setdash( m_gpc, 0, NULL, 0 ); break;
1655 }
1656
1657
1658 unsigned char red = m_pen.GetColour().Red();
1659 unsigned char blue = m_pen.GetColour().Blue();
1660 unsigned char green = m_pen.GetColour().Green();
1661
1662 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1663 {
1664 double redPS = (double)(red) / 255.0;
1665 double bluePS = (double)(blue) / 255.0;
1666 double greenPS = (double)(green) / 255.0;
1667
1668 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1669
1670 m_currentRed = red;
1671 m_currentBlue = blue;
1672 m_currentGreen = green;
1673 }
1674 }
1675
SetBrush(const wxBrush & brush)1676 void wxGnomePrintDC::SetBrush( const wxBrush& brush )
1677 {
1678 if (!brush.Ok()) return;
1679
1680 m_brush = brush;
1681
1682 // Brush colour
1683 unsigned char red = m_brush.GetColour().Red();
1684 unsigned char blue = m_brush.GetColour().Blue();
1685 unsigned char green = m_brush.GetColour().Green();
1686
1687 if (!m_colour)
1688 {
1689 // Anything not white is black
1690 if (! (red == (unsigned char) 255 &&
1691 blue == (unsigned char) 255 &&
1692 green == (unsigned char) 255) )
1693 {
1694 red = (unsigned char) 0;
1695 green = (unsigned char) 0;
1696 blue = (unsigned char) 0;
1697 }
1698 // setgray here ?
1699 }
1700
1701 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
1702 {
1703 double redPS = (double)(red) / 255.0;
1704 double bluePS = (double)(blue) / 255.0;
1705 double greenPS = (double)(green) / 255.0;
1706
1707 gs_lgp->gnome_print_setrgbcolor( m_gpc, redPS, greenPS, bluePS );
1708
1709 m_currentRed = red;
1710 m_currentBlue = blue;
1711 m_currentGreen = green;
1712 }
1713 }
1714
SetLogicalFunction(int function)1715 void wxGnomePrintDC::SetLogicalFunction( int function )
1716 {
1717 }
1718
SetBackground(const wxBrush & brush)1719 void wxGnomePrintDC::SetBackground( const wxBrush& brush )
1720 {
1721 }
1722
DoSetClippingRegion(wxCoord x,wxCoord y,wxCoord width,wxCoord height)1723 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
1724 {
1725 wxDC::DoSetClippingRegion( x, y, width, height );
1726
1727 gs_lgp->gnome_print_gsave( m_gpc );
1728
1729 gs_lgp->gnome_print_newpath( m_gpc );
1730 gs_lgp->gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
1731 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
1732 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
1733 gs_lgp->gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
1734 gs_lgp->gnome_print_closepath( m_gpc );
1735 gs_lgp->gnome_print_clip( m_gpc );
1736 }
1737
DestroyClippingRegion()1738 void wxGnomePrintDC::DestroyClippingRegion()
1739 {
1740 wxDC::DestroyClippingRegion();
1741
1742 gs_lgp->gnome_print_grestore( m_gpc );
1743
1744 #if 0
1745 // not needed, we set the values in each
1746 // drawing method anyways
1747 SetPen( m_pen );
1748 SetBrush( m_brush );
1749 SetFont( m_font );
1750 #endif
1751 }
1752
StartDoc(const wxString & message)1753 bool wxGnomePrintDC::StartDoc(const wxString& message)
1754 {
1755 return true;
1756 }
1757
EndDoc()1758 void wxGnomePrintDC::EndDoc()
1759 {
1760 gs_lgp->gnome_print_end_doc( m_gpc );
1761 }
1762
StartPage()1763 void wxGnomePrintDC::StartPage()
1764 {
1765 gs_lgp->gnome_print_beginpage( m_gpc, (const guchar*) "page" );
1766 }
1767
EndPage()1768 void wxGnomePrintDC::EndPage()
1769 {
1770 gs_lgp->gnome_print_showpage( m_gpc );
1771 }
1772
GetCharHeight() const1773 wxCoord wxGnomePrintDC::GetCharHeight() const
1774 {
1775 pango_layout_set_text( m_layout, "H", 1 );
1776
1777 int w,h;
1778 pango_layout_get_pixel_size( m_layout, &w, &h );
1779
1780 return h;
1781 }
1782
GetCharWidth() const1783 wxCoord wxGnomePrintDC::GetCharWidth() const
1784 {
1785 pango_layout_set_text( m_layout, "H", 1 );
1786
1787 int w,h;
1788 pango_layout_get_pixel_size( m_layout, &w, &h );
1789
1790 return w;
1791 }
1792
DoGetTextExtent(const wxString & string,wxCoord * width,wxCoord * height,wxCoord * descent,wxCoord * externalLeading,wxFont * theFont) const1793 void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxCoord *height,
1794 wxCoord *descent,
1795 wxCoord *externalLeading,
1796 wxFont *theFont ) const
1797 {
1798 if ( width )
1799 *width = 0;
1800 if ( height )
1801 *height = 0;
1802 if ( descent )
1803 *descent = 0;
1804 if ( externalLeading )
1805 *externalLeading = 0;
1806
1807 if (string.empty())
1808 {
1809 return;
1810 }
1811
1812 // Set layout's text
1813 #if wxUSE_UNICODE
1814 const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
1815 const char *dataUTF8 = (const char *)data;
1816 #else
1817 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string );
1818 if ( !wdata )
1819 {
1820 if (width) (*width) = 0;
1821 if (height) (*height) = 0;
1822 return;
1823 }
1824 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
1825 const char *dataUTF8 = (const char *)data;
1826 #endif
1827
1828 if ( !dataUTF8 )
1829 {
1830 // hardly ideal, but what else can we do if conversion failed?
1831 return;
1832 }
1833
1834 gint oldSize;
1835 if ( theFont )
1836 {
1837 // scale the font and apply it
1838 PangoFontDescription *desc = theFont->GetNativeFontInfo()->description;
1839 oldSize = pango_font_description_get_size(desc);
1840 float size = oldSize * GetFontPointSizeAdjustment(72.0);
1841 pango_font_description_set_size(desc, (gint)size);
1842
1843 pango_layout_set_font_description(m_layout, desc);
1844 }
1845
1846 pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
1847
1848 int h;
1849 pango_layout_get_pixel_size( m_layout, width, &h );
1850 if ( height )
1851 *height = h;
1852
1853 if (descent)
1854 {
1855 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
1856 int baseline = pango_layout_iter_get_baseline(iter);
1857 pango_layout_iter_free(iter);
1858 *descent = h - PANGO_PIXELS(baseline);
1859 }
1860
1861 if ( theFont )
1862 {
1863 // restore font and reset font's size back
1864 pango_layout_set_font_description(m_layout, m_fontdesc);
1865
1866 PangoFontDescription *desc = theFont->GetNativeFontInfo()->description;
1867 pango_font_description_set_size(desc, oldSize);
1868 }
1869 }
1870
DoGetSize(int * width,int * height) const1871 void wxGnomePrintDC::DoGetSize(int* width, int* height) const
1872 {
1873 wxGnomePrintNativeData *native =
1874 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1875
1876 // Query page size. This seems to omit the margins
1877 double pw,ph;
1878 gs_lgp->gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1879
1880 if (width)
1881 *width = (int) (pw + 0.5);
1882 if (height)
1883 *height = (int) (ph + 0.5);
1884 }
1885
DoGetSizeMM(int * width,int * height) const1886 void wxGnomePrintDC::DoGetSizeMM(int *width, int *height) const
1887 {
1888 wxGnomePrintNativeData *native =
1889 (wxGnomePrintNativeData*) m_printData.GetNativeData();
1890
1891 // This code assumes values in Pts.
1892
1893 double pw,ph;
1894 gs_lgp->gnome_print_job_get_page_size( native->GetPrintJob(), &pw, &ph );
1895
1896 // Convert to mm.
1897
1898 const GnomePrintUnit *mm_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "mm" );
1899 const GnomePrintUnit *pts_unit = gs_lgp->gnome_print_unit_get_by_abbreviation( (const guchar*) "Pts" );
1900 gs_lgp->gnome_print_convert_distance( &pw, pts_unit, mm_unit );
1901 gs_lgp->gnome_print_convert_distance( &ph, pts_unit, mm_unit );
1902
1903 if (width)
1904 *width = (int) (pw + 0.5);
1905 if (height)
1906 *height = (int) (ph + 0.5);
1907 }
1908
GetPPI() const1909 wxSize wxGnomePrintDC::GetPPI() const
1910 {
1911 return wxSize(72,72);
1912 }
1913
SetAxisOrientation(bool xLeftRight,bool yBottomUp)1914 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
1915 {
1916 m_signX = (xLeftRight ? 1 : -1);
1917 m_signY = (yBottomUp ? 1 : -1);
1918
1919 ComputeScaleAndOrigin();
1920 }
1921
SetLogicalOrigin(wxCoord x,wxCoord y)1922 void wxGnomePrintDC::SetLogicalOrigin( wxCoord x, wxCoord y )
1923 {
1924 wxDC::SetLogicalOrigin( x, y );
1925 }
1926
SetDeviceOrigin(wxCoord x,wxCoord y)1927 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x, wxCoord y )
1928 {
1929 wxDC::SetDeviceOrigin( x, y );
1930 }
1931
SetPrintData(const wxPrintData & data)1932 void wxGnomePrintDC::SetPrintData(const wxPrintData& data)
1933 {
1934 m_printData = data;
1935
1936 if (m_printData.GetOrientation() == wxPORTRAIT)
1937 GetSize( NULL, &m_deviceOffsetY );
1938 else
1939 GetSize( &m_deviceOffsetY, NULL );
1940 }
1941
SetResolution(int ppi)1942 void wxGnomePrintDC::SetResolution(int ppi)
1943 {
1944 }
1945
GetResolution()1946 int wxGnomePrintDC::GetResolution()
1947 {
1948 return 72;
1949 }
1950
1951
1952 class wxGnomePrintModule: public wxModule
1953 {
1954 public:
wxGnomePrintModule()1955 wxGnomePrintModule() {}
1956 bool OnInit();
1957 void OnExit();
1958
1959 private:
1960 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule)
1961 };
1962
OnInit()1963 bool wxGnomePrintModule::OnInit()
1964 {
1965 gs_lgp = new wxGnomePrintLibrary;
1966 if (gs_lgp->IsOk())
1967 wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory );
1968 return true;
1969 }
1970
OnExit()1971 void wxGnomePrintModule::OnExit()
1972 {
1973 delete gs_lgp;
1974 }
1975
IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule,wxModule)1976 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule, wxModule)
1977
1978 // ----------------------------------------------------------------------------
1979 // Print preview
1980 // ----------------------------------------------------------------------------
1981
1982 IMPLEMENT_CLASS(wxGnomePrintPreview, wxPrintPreviewBase)
1983
1984 void wxGnomePrintPreview::Init(wxPrintout * WXUNUSED(printout),
1985 wxPrintout * WXUNUSED(printoutForPrinting))
1986 {
1987 DetermineScaling();
1988 }
1989
wxGnomePrintPreview(wxPrintout * printout,wxPrintout * printoutForPrinting,wxPrintDialogData * data)1990 wxGnomePrintPreview::wxGnomePrintPreview(wxPrintout *printout,
1991 wxPrintout *printoutForPrinting,
1992 wxPrintDialogData *data)
1993 : wxPrintPreviewBase(printout, printoutForPrinting, data)
1994 {
1995 Init(printout, printoutForPrinting);
1996 }
1997
wxGnomePrintPreview(wxPrintout * printout,wxPrintout * printoutForPrinting,wxPrintData * data)1998 wxGnomePrintPreview::wxGnomePrintPreview(wxPrintout *printout,
1999 wxPrintout *printoutForPrinting,
2000 wxPrintData *data)
2001 : wxPrintPreviewBase(printout, printoutForPrinting, data)
2002 {
2003 Init(printout, printoutForPrinting);
2004 }
2005
~wxGnomePrintPreview()2006 wxGnomePrintPreview::~wxGnomePrintPreview()
2007 {
2008 }
2009
Print(bool interactive)2010 bool wxGnomePrintPreview::Print(bool interactive)
2011 {
2012 if (!m_printPrintout)
2013 return false;
2014
2015 wxPrinter printer(& m_printDialogData);
2016 return printer.Print(m_previewFrame, m_printPrintout, interactive);
2017 }
2018
DetermineScaling()2019 void wxGnomePrintPreview::DetermineScaling()
2020 {
2021 wxPaperSize paperType = m_printDialogData.GetPrintData().GetPaperId();
2022 if (paperType == wxPAPER_NONE)
2023 paperType = wxPAPER_NONE;
2024
2025 wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
2026 if (!paper)
2027 paper = wxThePrintPaperDatabase->FindPaperType(wxPAPER_A4);
2028
2029 if (paper)
2030 {
2031 wxSize ScreenPixels = wxGetDisplaySize();
2032 wxSize ScreenMM = wxGetDisplaySizeMM();
2033
2034 m_previewPrintout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()),
2035 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) );
2036 m_previewPrintout->SetPPIPrinter(wxGnomePrintDC::GetResolution(), wxGnomePrintDC::GetResolution());
2037
2038 wxSize sizeDevUnits(paper->GetSizeDeviceUnits());
2039
2040 // TODO: get better resolution information from wxGnomePrintDC, if possible.
2041
2042 sizeDevUnits.x = (wxCoord)((float)sizeDevUnits.x * wxGnomePrintDC::GetResolution() / 72.0);
2043 sizeDevUnits.y = (wxCoord)((float)sizeDevUnits.y * wxGnomePrintDC::GetResolution() / 72.0);
2044 wxSize sizeTenthsMM(paper->GetSize());
2045 wxSize sizeMM(sizeTenthsMM.x / 10, sizeTenthsMM.y / 10);
2046
2047 // If in landscape mode, we need to swap the width and height.
2048 if ( m_printDialogData.GetPrintData().GetOrientation() == wxLANDSCAPE )
2049 {
2050 m_pageWidth = sizeDevUnits.y;
2051 m_pageHeight = sizeDevUnits.x;
2052 m_previewPrintout->SetPageSizeMM(sizeMM.y, sizeMM.x);
2053 }
2054 else
2055 {
2056 m_pageWidth = sizeDevUnits.x;
2057 m_pageHeight = sizeDevUnits.y;
2058 m_previewPrintout->SetPageSizeMM(sizeMM.x, sizeMM.y);
2059 }
2060 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
2061 m_previewPrintout->SetPaperRectPixels(wxRect(0, 0, m_pageWidth, m_pageHeight));
2062
2063 // At 100%, the page should look about page-size on the screen.
2064 m_previewScaleX = (float)0.8 * 72.0 / (float)wxGnomePrintDC::GetResolution();
2065 m_previewScaleY = m_previewScaleX;
2066 }
2067 }
2068
2069 #endif
2070 // wxUSE_LIBGNOMEPRINT
2071