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