]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/gnome/gprint.cpp
Added support for native print preview (GNOME)
[wxWidgets.git] / src / gtk1 / gnome / gprint.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gprint.cpp
3 // Author: Robert Roebling
4 // Purpose: Implement GNOME printing support
5 // Created: 09/20/04
6 // Copyright: Robert Roebling
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
11 #pragma implementation "gprint.h"
12 #endif
13
14 // For compilers that support precompilation, includes "wx/wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #include "wx/gtk/gnome/gprint.h"
22
23 #if wxUSE_LIBGNOMEPRINT
24
25 #include "math.h"
26
27 #include "wx/fontutil.h"
28 #include "wx/printdlg.h"
29 #include "wx/gtk/private.h"
30
31 #include <libgnomeprint/gnome-print.h>
32 #include <libgnomeprint/gnome-print-pango.h>
33 #include <libgnomeprintui/gnome-print-dialog.h>
34 #include <libgnomeprintui/gnome-print-job-preview.h>
35
36 //----------------------------------------------------------------------------
37 // wxGnomePrintNativeData
38 //----------------------------------------------------------------------------
39
40 IMPLEMENT_CLASS(wxGnomePrintNativeData, wxPrintNativeDataBase)
41
42 wxGnomePrintNativeData::wxGnomePrintNativeData()
43 {
44 m_config = gnome_print_config_default();
45 m_job = gnome_print_job_new( m_config );
46 }
47
48 wxGnomePrintNativeData::~wxGnomePrintNativeData()
49 {
50 g_object_unref (G_OBJECT (m_config));
51 g_object_unref (G_OBJECT (m_job));
52 }
53
54 bool wxGnomePrintNativeData::TransferTo( wxPrintData &data )
55 {
56 // TODO
57 return true;
58 }
59
60 bool wxGnomePrintNativeData::TransferFrom( const wxPrintData &data )
61 {
62 // TODO
63 return true;
64 }
65
66 //----------------------------------------------------------------------------
67 // wxGnomePrintFactory
68 //----------------------------------------------------------------------------
69
70 wxPrinterBase* wxGnomePrintFactory::CreatePrinter( wxPrintDialogData *data )
71 {
72 return new wxGnomePrinter( data );
73 }
74
75 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
76 wxPrintout *printout,
77 wxPrintDialogData *data )
78 {
79 return new wxPostScriptPrintPreview( preview, printout, data );
80 }
81
82 wxPrintPreviewBase *wxGnomePrintFactory::CreatePrintPreview( wxPrintout *preview,
83 wxPrintout *printout,
84 wxPrintData *data )
85 {
86 return new wxPostScriptPrintPreview( preview, printout, data );
87 }
88
89 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
90 wxPrintDialogData *data )
91 {
92 return new wxGnomePrintDialog( parent, data );
93 }
94
95 wxPrintDialogBase *wxGnomePrintFactory::CreatePrintDialog( wxWindow *parent,
96 wxPrintData *data )
97 {
98 return new wxGnomePrintDialog( parent, data );
99 }
100
101 bool wxGnomePrintFactory::HasPrintSetupDialog()
102 {
103 return false;
104 }
105
106 wxDialog *wxGnomePrintFactory::CreatePrintSetupDialog( wxWindow *parent, wxPrintData *data )
107 {
108 return NULL;
109 }
110
111 bool wxGnomePrintFactory::HasOwnPrintToFile()
112 {
113 return true;
114 }
115
116 bool wxGnomePrintFactory::HasPrinterLine()
117 {
118 return true;
119 }
120
121 wxString wxGnomePrintFactory::CreatePrinterLine()
122 {
123 // redundant now
124 return wxEmptyString;
125 }
126
127 bool wxGnomePrintFactory::HasStatusLine()
128 {
129 // redundant now
130 return true;
131 }
132
133 wxString wxGnomePrintFactory::CreateStatusLine()
134 {
135 // redundant now
136 return wxEmptyString;
137 }
138
139 wxPrintNativeDataBase *wxGnomePrintFactory::CreatePrintNativeData()
140 {
141 return new wxGnomePrintNativeData;
142 }
143
144 //----------------------------------------------------------------------------
145 // wxGnomePrintSetupDialog
146 //----------------------------------------------------------------------------
147
148 IMPLEMENT_CLASS(wxGnomePrintDialog, wxPrintDialogBase)
149
150 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow *parent, wxPrintDialogData *data )
151 : wxPrintDialogBase(parent, wxID_ANY, _("Print"),
152 wxPoint(0, 0), wxSize(600, 600),
153 wxDEFAULT_DIALOG_STYLE |
154 wxTAB_TRAVERSAL)
155 {
156 if (data)
157 m_printDialogData = *data;
158
159 Init();
160 }
161
162 wxGnomePrintDialog::wxGnomePrintDialog( wxWindow *parent, wxPrintData *data )
163 : wxPrintDialogBase(parent, wxID_ANY, _("Print"),
164 wxPoint(0, 0), wxSize(600, 600),
165 wxDEFAULT_DIALOG_STYLE |
166 wxTAB_TRAVERSAL)
167 {
168 if (data)
169 m_printDialogData = *data;
170
171 Init();
172 }
173
174 void wxGnomePrintDialog::Init()
175 {
176 wxPrintData data = m_printDialogData.GetPrintData();
177
178 wxGnomePrintNativeData *native =
179 (wxGnomePrintNativeData*) data.GetNativeData();
180
181 m_widget = gnome_print_dialog_new( native->GetPrintJob(),
182 (guchar*)"Print",
183 GNOME_PRINT_DIALOG_RANGE|GNOME_PRINT_DIALOG_COPIES );
184
185 int flag = 0;
186 if (m_printDialogData.GetEnableSelection())
187 flag |= GNOME_PRINT_RANGE_SELECTION;
188 if (m_printDialogData.GetEnablePageNumbers())
189 flag |= GNOME_PRINT_RANGE_ALL|GNOME_PRINT_RANGE_RANGE;
190
191 gnome_print_dialog_construct_range_page( GNOME_PRINT_DIALOG( m_widget ),
192 flag,
193 m_printDialogData.GetMinPage(),
194 m_printDialogData.GetMaxPage(),
195 NULL,
196 NULL );
197 }
198
199 wxGnomePrintDialog::~wxGnomePrintDialog()
200 {
201 m_widget = NULL;
202 }
203
204 int wxGnomePrintDialog::ShowModal()
205 {
206 // Transfer data from m_printDalogData to dialog here
207
208 int response = gtk_dialog_run (GTK_DIALOG (m_widget));
209
210 if (response == GNOME_PRINT_DIALOG_RESPONSE_CANCEL)
211 {
212 gtk_widget_destroy(m_widget);
213 m_widget = NULL;
214
215 return wxID_CANCEL;
216 }
217
218 gint copies = 1;
219 gboolean collate = false;
220 gnome_print_dialog_get_copies( GNOME_PRINT_DIALOG(m_widget), &copies, &collate );
221 m_printDialogData.SetNoCopies( copies );
222 m_printDialogData.SetCollate( collate );
223
224 switch (gnome_print_dialog_get_range( GNOME_PRINT_DIALOG(m_widget) ))
225 {
226 case GNOME_PRINT_RANGE_SELECTION:
227 m_printDialogData.SetSelection( true );
228 break;
229 case GNOME_PRINT_RANGE_ALL:
230 m_printDialogData.SetAllPages( true );
231 m_printDialogData.SetFromPage( 0 );
232 m_printDialogData.SetToPage( 9999 );
233 break;
234 case GNOME_PRINT_RANGE_RANGE:
235 default:
236 gint start,end;
237 gnome_print_dialog_get_range_page( GNOME_PRINT_DIALOG(m_widget), &start, &end );
238 m_printDialogData.SetFromPage( start );
239 m_printDialogData.SetToPage( end );
240 break;
241 }
242
243 gtk_widget_destroy(m_widget);
244 m_widget = NULL;
245
246 if (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW)
247 return wxID_PREVIEW;
248
249 return wxID_OK;
250 }
251
252 wxDC *wxGnomePrintDialog::GetPrintDC()
253 {
254 // Later
255 return NULL;
256 }
257
258 bool wxGnomePrintDialog::Validate()
259 {
260 return true;
261 }
262
263 bool wxGnomePrintDialog::TransferDataToWindow()
264 {
265 return true;
266 }
267
268 bool wxGnomePrintDialog::TransferDataFromWindow()
269 {
270 return true;
271 }
272
273 //----------------------------------------------------------------------------
274 // wxGnomePrinter
275 //----------------------------------------------------------------------------
276
277 IMPLEMENT_CLASS(wxGnomePrinter, wxPrinterBase)
278
279 wxGnomePrinter::wxGnomePrinter( wxPrintDialogData *data ) :
280 wxPrinterBase( data )
281 {
282 m_gpc = NULL;
283 m_native_preview = false;
284 }
285
286 wxGnomePrinter::~wxGnomePrinter()
287 {
288 }
289
290 bool wxGnomePrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt )
291 {
292 if (!printout)
293 {
294 sm_lastError = wxPRINTER_ERROR;
295 return false;
296 }
297
298 wxPrintData printdata = GetPrintDialogData().GetPrintData();
299 wxGnomePrintNativeData *data =
300 (wxGnomePrintNativeData*) printdata.GetNativeData();
301
302 // The GnomePrintJob is temporarily stored in the
303 // native print data as the native print dialog
304 // needs to access it.
305 GnomePrintJob *job = data->GetPrintJob();
306 m_gpc = gnome_print_job_get_context (job);
307
308 printout->SetIsPreview(false);
309
310 if (m_printDialogData.GetMinPage() < 1)
311 m_printDialogData.SetMinPage(1);
312 if (m_printDialogData.GetMaxPage() < 1)
313 m_printDialogData.SetMaxPage(9999);
314
315 wxDC *dc;
316 if (prompt)
317 dc = PrintDialog( parent );
318 else
319 dc = new wxGnomePrintDC( this );
320
321 if (m_native_preview)
322 printout->SetIsPreview(true);
323
324 if (!dc)
325 {
326 gnome_print_job_close( job );
327 sm_lastError = wxPRINTER_ERROR;
328 return false;
329 }
330
331 wxSize ScreenPixels = wxGetDisplaySize();
332 wxSize ScreenMM = wxGetDisplaySizeMM();
333
334 printout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()),
335 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) );
336 printout->SetPPIPrinter( wxGnomePrintDC::GetResolution(),
337 wxGnomePrintDC::GetResolution() );
338
339 printout->SetDC(dc);
340
341 int w, h;
342 dc->GetSize(&w, &h);
343 printout->SetPageSizePixels((int)w, (int)h);
344 dc->GetSizeMM(&w, &h);
345 printout->SetPageSizeMM((int)w, (int)h);
346
347 printout->OnPreparePrinting();
348
349 // Get some parameters from the printout, if defined
350 int fromPage, toPage;
351 int minPage, maxPage;
352 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
353
354 if (maxPage == 0)
355 {
356 sm_lastError = wxPRINTER_ERROR;
357 return false;
358 }
359
360 printout->OnBeginPrinting();
361
362 int minPageNum = minPage, maxPageNum = maxPage;
363
364 if ( !m_printDialogData.GetAllPages() )
365 {
366 minPageNum = m_printDialogData.GetFromPage();
367 maxPageNum = m_printDialogData.GetToPage();
368 }
369
370
371 int copyCount;
372 for ( copyCount = 1;
373 copyCount <= m_printDialogData.GetNoCopies();
374 copyCount++ )
375 {
376 if (!printout->OnBeginDocument(minPageNum, maxPageNum))
377 {
378 wxLogError(_("Could not start printing."));
379 sm_lastError = wxPRINTER_ERROR;
380 break;
381 }
382
383 int pn;
384 for ( pn = minPageNum;
385 pn <= maxPageNum && printout->HasPage(pn);
386 pn++ )
387 {
388 dc->StartPage();
389 printout->OnPrintPage(pn);
390 dc->EndPage();
391 }
392
393 printout->OnEndDocument();
394 printout->OnEndPrinting();
395 }
396
397 gnome_print_job_close( job );
398 if (m_native_preview)
399 {
400 wxString title( _("Print preview") );
401 gtk_widget_show( gnome_print_job_preview_new( job, (const guchar*)(const char*)wxGTK_CONV(title) ));
402 }
403 else
404 {
405 gnome_print_job_print( job );
406 }
407
408 delete dc;
409
410 return (sm_lastError == wxPRINTER_NO_ERROR);
411 }
412
413 wxDC* wxGnomePrinter::PrintDialog( wxWindow *parent )
414 {
415 wxGnomePrintDialog dialog( parent, &m_printDialogData );
416 int ret = dialog.ShowModal();
417 if (ret == wxID_CANCEL)
418 {
419 sm_lastError = wxPRINTER_ERROR;
420 return NULL;
421 }
422
423 m_native_preview = ret == wxID_PREVIEW;
424
425 m_printDialogData = dialog.GetPrintDialogData();
426 return new wxGnomePrintDC( this );
427 }
428
429 bool wxGnomePrinter::Setup( wxWindow *parent )
430 {
431 return false;
432 }
433
434 //-----------------------------------------------------------------------------
435 // wxGnomePrintDC
436 //-----------------------------------------------------------------------------
437
438 IMPLEMENT_CLASS(wxGnomePrintDC, wxDCBase)
439
440 wxGnomePrintDC::wxGnomePrintDC( wxGnomePrinter *printer )
441 {
442 m_printer = printer;
443
444 m_gpc = printer->GetPrintContext();
445
446 m_layout = gnome_print_pango_create_layout( m_gpc );
447 m_fontdesc = pango_font_description_from_string( "Sans 12" );
448
449 m_currentRed = 0;
450 m_currentBlue = 0;
451 m_currentGreen = 0;
452
453 m_signX = 1; // default x-axis left to right
454 m_signY = -1; // default y-axis bottom up -> top down
455 }
456
457 wxGnomePrintDC::~wxGnomePrintDC()
458 {
459 }
460
461 bool wxGnomePrintDC::Ok() const
462 {
463 return true;
464 }
465
466 bool wxGnomePrintDC::DoFloodFill(wxCoord x1, wxCoord y1, const wxColour &col, int style )
467 {
468 return false;
469 }
470
471 bool wxGnomePrintDC::DoGetPixel(wxCoord x1, wxCoord y1, wxColour *col) const
472 {
473 return false;
474 }
475
476 void wxGnomePrintDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
477 {
478 if (m_pen.GetStyle() == wxTRANSPARENT) return;
479
480 SetPen( m_pen );
481
482 gnome_print_moveto ( m_gpc, XLOG2DEV(x1), YLOG2DEV(y1) );
483 gnome_print_lineto ( m_gpc, XLOG2DEV(x2), YLOG2DEV(y2) );
484 gnome_print_stroke ( m_gpc);
485
486 CalcBoundingBox( x1, y1 );
487 CalcBoundingBox( x2, y2 );
488 }
489
490 void wxGnomePrintDC::DoCrossHair(wxCoord x, wxCoord y)
491 {
492 }
493
494 void wxGnomePrintDC::DoDrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2,wxCoord xc,wxCoord yc)
495 {
496 }
497
498 void wxGnomePrintDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)
499 {
500 }
501
502 void wxGnomePrintDC::DoDrawPoint(wxCoord x, wxCoord y)
503 {
504 }
505
506 void wxGnomePrintDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset)
507 {
508 }
509
510 void wxGnomePrintDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
511 {
512 }
513
514 void wxGnomePrintDC::DoDrawPolyPolygon(int n, int count[], wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
515 {
516 }
517
518 void wxGnomePrintDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
519 {
520 if (m_brush.GetStyle () != wxTRANSPARENT)
521 {
522 SetBrush( m_brush );
523
524 gnome_print_newpath( m_gpc );
525 gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
526 gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
527 gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
528 gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
529 gnome_print_closepath( m_gpc );
530 gnome_print_fill( m_gpc );
531
532 CalcBoundingBox( x, y );
533 CalcBoundingBox( x + width, y + height );
534 }
535
536 if (m_pen.GetStyle () != wxTRANSPARENT)
537 {
538 SetPen (m_pen);
539
540 gnome_print_newpath( m_gpc );
541 gnome_print_moveto( m_gpc, XLOG2DEV(x), YLOG2DEV(y) );
542 gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y) );
543 gnome_print_lineto( m_gpc, XLOG2DEV(x + width), YLOG2DEV(y + height) );
544 gnome_print_lineto( m_gpc, XLOG2DEV(x), YLOG2DEV(y + height) );
545 gnome_print_closepath( m_gpc );
546 gnome_print_stroke( m_gpc );
547
548 CalcBoundingBox( x, y );
549 CalcBoundingBox( x + width, y + height );
550 }
551 }
552
553 void wxGnomePrintDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
554 {
555 }
556
557 void wxGnomePrintDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
558 {
559 }
560
561 void wxGnomePrintDC::DoDrawSpline(wxList *points)
562 {
563 }
564
565 bool wxGnomePrintDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
566 wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
567 wxCoord xsrcMask, wxCoord ysrcMask)
568 {
569 return false;
570 }
571
572 void wxGnomePrintDC::DoDrawIcon( const wxIcon& icon, wxCoord x, wxCoord y )
573 {
574 DoDrawBitmap( icon, x, y, true );
575 }
576
577 void wxGnomePrintDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool useMask )
578 {
579 if (!bitmap.Ok()) return;
580
581 if (bitmap.HasPixbuf())
582 {
583 GdkPixbuf *pixbuf = bitmap.GetPixbuf();
584 guchar *raw_image = gdk_pixbuf_get_pixels( pixbuf );
585 bool has_alpha = gdk_pixbuf_get_has_alpha( pixbuf );
586 int rowstride = gdk_pixbuf_get_rowstride( pixbuf );
587 int height = gdk_pixbuf_get_height( pixbuf );
588 int width = gdk_pixbuf_get_width( pixbuf );
589
590 gnome_print_gsave( m_gpc );
591 double matrix[6];
592 matrix[0] = XLOG2DEVREL(width);
593 matrix[1] = 0;
594 matrix[2] = 0;
595 matrix[3] = YLOG2DEVREL(height);
596 matrix[4] = XLOG2DEV(x);
597 matrix[5] = YLOG2DEV(y+height);
598 gnome_print_concat( m_gpc, matrix );
599 gnome_print_moveto( m_gpc, 0, 0 );
600 if (has_alpha)
601 gnome_print_rgbaimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
602 else
603 gnome_print_rgbimage( m_gpc, (guchar *)raw_image, width, height, rowstride );
604 gnome_print_grestore( m_gpc );
605 }
606 else
607 {
608 wxImage image = bitmap.ConvertToImage();
609
610 if (!image.Ok()) return;
611
612 gnome_print_gsave( m_gpc );
613 double matrix[6];
614 matrix[0] = XLOG2DEVREL(image.GetWidth());
615 matrix[1] = 0;
616 matrix[2] = 0;
617 matrix[3] = YLOG2DEVREL(image.GetHeight());
618 matrix[4] = XLOG2DEV(x);
619 matrix[5] = YLOG2DEV(y+image.GetHeight());
620 gnome_print_concat( m_gpc, matrix );
621 gnome_print_moveto( m_gpc, 0, 0 );
622 gnome_print_rgbimage( m_gpc, (guchar*) image.GetData(), image.GetWidth(), image.GetHeight(), image.GetWidth()*3 );
623 gnome_print_grestore( m_gpc );
624 }
625 }
626
627 void wxGnomePrintDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y )
628 {
629 DoDrawRotatedText( text, x, y, 0.0 );
630 }
631
632 void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
633 {
634 x = XLOG2DEV(x);
635 y = YLOG2DEV(y);
636
637 bool underlined = m_font.Ok() && m_font.GetUnderlined();
638
639 #if wxUSE_UNICODE
640 const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
641 #else
642 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text );
643 if ( !wdata )
644 return;
645 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
646 #endif
647
648 size_t datalen = strlen((const char*)data);
649 pango_layout_set_text( m_layout, (const char*) data, datalen);
650
651 if (underlined)
652 {
653 PangoAttrList *attrs = pango_attr_list_new();
654 PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
655 a->start_index = 0;
656 a->end_index = datalen;
657 pango_attr_list_insert(attrs, a);
658 pango_layout_set_attributes(m_layout, attrs);
659 pango_attr_list_unref(attrs);
660 }
661
662 if (m_textForegroundColour.Ok())
663 {
664 unsigned char red = m_textForegroundColour.Red();
665 unsigned char blue = m_textForegroundColour.Blue();
666 unsigned char green = m_textForegroundColour.Green();
667
668 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
669 {
670 double redPS = (double)(red) / 255.0;
671 double bluePS = (double)(blue) / 255.0;
672 double greenPS = (double)(green) / 255.0;
673
674 gnome_print_setrgbcolor( m_gpc, redPS, bluePS, greenPS );
675
676 m_currentRed = red;
677 m_currentBlue = blue;
678 m_currentGreen = green;
679 }
680 }
681
682 int w,h;
683
684 if (fabs(m_scaleY - 1.0) > 0.00001)
685 {
686 // If there is a user or actually any scale applied to
687 // the device context, scale the font.
688
689 // scale font description
690 gint oldSize = pango_font_description_get_size( m_fontdesc );
691 double size = oldSize;
692 size = size * m_scaleY;
693 pango_font_description_set_size( m_fontdesc, (gint)size );
694
695 // actually apply scaled font
696 pango_layout_set_font_description( m_layout, m_fontdesc );
697
698 pango_layout_get_pixel_size( m_layout, &w, &h );
699 #if 0
700 if ( m_backgroundMode == wxSOLID )
701 {
702 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
703 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
704 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
705 }
706 #endif
707 // Draw layout.
708 gnome_print_moveto (m_gpc, x, y);
709 if (fabs(angle) > 0.00001)
710 {
711 gnome_print_gsave( m_gpc );
712 gnome_print_rotate( m_gpc, angle );
713 gnome_print_pango_layout( m_gpc, m_layout );
714 gnome_print_grestore( m_gpc );
715 }
716 else
717 {
718 gnome_print_pango_layout( m_gpc, m_layout );
719 }
720
721 // reset unscaled size
722 pango_font_description_set_size( m_fontdesc, oldSize );
723
724 // actually apply unscaled font
725 pango_layout_set_font_description( m_layout, m_fontdesc );
726 }
727 else
728 {
729 pango_layout_get_pixel_size( m_layout, &w, &h );
730 #if 0
731 if ( m_backgroundMode == wxSOLID )
732 {
733 gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
734 gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h);
735 gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
736 }
737 #endif
738 // Draw layout.
739 gnome_print_moveto (m_gpc, x, y);
740 if (fabs(angle) > 0.00001)
741 {
742 gnome_print_gsave( m_gpc );
743 gnome_print_rotate( m_gpc, angle );
744 gnome_print_pango_layout( m_gpc, m_layout );
745 gnome_print_grestore( m_gpc );
746 }
747 else
748 {
749 gnome_print_pango_layout( m_gpc, m_layout );
750 }
751 }
752
753 if (underlined)
754 {
755 // undo underline attributes setting:
756 pango_layout_set_attributes(m_layout, NULL);
757 }
758
759 CalcBoundingBox (x + w, y + h);
760 }
761
762 void wxGnomePrintDC::Clear()
763 {
764 }
765
766 void wxGnomePrintDC::SetFont( const wxFont& font )
767 {
768 m_font = font;
769
770 if (m_font.Ok())
771 {
772 if (m_fontdesc)
773 pango_font_description_free( m_fontdesc );
774
775 m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description );
776
777 pango_layout_set_font_description( m_layout, m_fontdesc );
778 }
779 }
780
781 void wxGnomePrintDC::SetPen( const wxPen& pen )
782 {
783 if (!pen.Ok()) return;
784
785 // TODO: support for pen styles other than solid (use gnome_print_setdash)
786
787 m_pen = pen;
788
789 gnome_print_setlinewidth( m_gpc, XLOG2DEVREL( 1000 * m_pen.GetWidth() ) / 1000.0f );
790
791 unsigned char red = m_pen.GetColour().Red();
792 unsigned char blue = m_pen.GetColour().Blue();
793 unsigned char green = m_pen.GetColour().Green();
794
795 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
796 {
797 double redPS = (double)(red) / 255.0;
798 double bluePS = (double)(blue) / 255.0;
799 double greenPS = (double)(green) / 255.0;
800
801 gnome_print_setrgbcolor( m_gpc, redPS, bluePS, greenPS );
802
803 m_currentRed = red;
804 m_currentBlue = blue;
805 m_currentGreen = green;
806 }
807 }
808
809 void wxGnomePrintDC::SetBrush( const wxBrush& brush )
810 {
811 if (!brush.Ok()) return;
812
813 m_brush = brush;
814
815 // Brush colour
816 unsigned char red = m_brush.GetColour().Red();
817 unsigned char blue = m_brush.GetColour().Blue();
818 unsigned char green = m_brush.GetColour().Green();
819
820 if (!m_colour)
821 {
822 // Anything not white is black
823 if (! (red == (unsigned char) 255 &&
824 blue == (unsigned char) 255 &&
825 green == (unsigned char) 255) )
826 {
827 red = (unsigned char) 0;
828 green = (unsigned char) 0;
829 blue = (unsigned char) 0;
830 }
831 // setgray here ?
832 }
833
834 if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
835 {
836 double redPS = (double)(red) / 255.0;
837 double bluePS = (double)(blue) / 255.0;
838 double greenPS = (double)(green) / 255.0;
839
840 gnome_print_setrgbcolor( m_gpc, redPS, bluePS, greenPS );
841
842 m_currentRed = red;
843 m_currentBlue = blue;
844 m_currentGreen = green;
845 }
846 }
847
848 void wxGnomePrintDC::SetLogicalFunction( int function )
849 {
850 }
851
852 void wxGnomePrintDC::SetBackground( const wxBrush& brush )
853 {
854 }
855
856 void wxGnomePrintDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
857 {
858 }
859
860 void wxGnomePrintDC::DestroyClippingRegion()
861 {
862 }
863
864 bool wxGnomePrintDC::StartDoc(const wxString& message)
865 {
866 SetDeviceOrigin( 0,0 );
867
868 return true;
869 }
870
871 void wxGnomePrintDC::EndDoc()
872 {
873 }
874
875 void wxGnomePrintDC::StartPage()
876 {
877 gnome_print_beginpage( m_gpc, (const guchar*) "1" );
878 }
879
880 void wxGnomePrintDC::EndPage()
881 {
882 gnome_print_showpage( m_gpc );
883 }
884
885 wxCoord wxGnomePrintDC::GetCharHeight() const
886 {
887 pango_layout_set_text( m_layout, "H", 1 );
888
889 int w,h;
890 pango_layout_get_pixel_size( m_layout, &w, &h );
891
892 return h;
893 }
894
895 wxCoord wxGnomePrintDC::GetCharWidth() const
896 {
897 pango_layout_set_text( m_layout, "H", 1 );
898
899 int w,h;
900 pango_layout_get_pixel_size( m_layout, &w, &h );
901
902 return w;
903 }
904
905 void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxCoord *height,
906 wxCoord *descent,
907 wxCoord *externalLeading,
908 wxFont *theFont ) const
909 {
910 if ( width )
911 *width = 0;
912 if ( height )
913 *height = 0;
914 if ( descent )
915 *descent = 0;
916 if ( externalLeading )
917 *externalLeading = 0;
918
919 if (string.IsEmpty())
920 {
921 return;
922 }
923
924 // Set new font description
925 if (theFont)
926 pango_layout_set_font_description( m_layout, theFont->GetNativeFontInfo()->description );
927
928 // Set layout's text
929 #if wxUSE_UNICODE
930 const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
931 const char *dataUTF8 = (const char *)data;
932 #else
933 const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string );
934 if ( !wdata )
935 {
936 if (width) (*width) = 0;
937 if (height) (*height) = 0;
938 return;
939 }
940 const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
941 const char *dataUTF8 = (const char *)data;
942 #endif
943
944 if ( !dataUTF8 )
945 {
946 // hardly ideal, but what else can we do if conversion failed?
947 return;
948 }
949
950 pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
951
952 int w,h;
953 pango_layout_get_pixel_size( m_layout, &w, &h );
954
955 if (width)
956 *width = (wxCoord) w;
957 if (height)
958 *height = (wxCoord) h;
959 if (descent)
960 {
961 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
962 int baseline = pango_layout_iter_get_baseline(iter);
963 pango_layout_iter_free(iter);
964 *descent = h - PANGO_PIXELS(baseline);
965 }
966
967 // Reset old font description
968 if (theFont)
969 pango_layout_set_font_description( m_layout, m_fontdesc );
970 }
971
972 void wxGnomePrintDC::DoGetSize(int* width, int* height) const
973 {
974 // No idea if that is efficient
975 GnomePrintConfig *config = gnome_print_config_default();
976
977 double w,h;
978 bool result = gnome_print_config_get_page_size( config, &w, &h );
979
980 if (!result)
981 {
982 // Standard PS resolution DIN A4 size.
983 w = 595.0;
984 h = 842.0;
985 }
986
987 if (width)
988 *width = (int) w;
989 if (height)
990 *height = (int) h;
991 }
992
993 void wxGnomePrintDC::DoGetSizeMM(int *width, int *height) const
994 {
995 double w,h;
996
997 /// Later, for now DIN A4
998 w = 210.0;
999 h = 297.0;
1000
1001 if (width)
1002 *width = (int) w;
1003 if (height)
1004 *height = (int) h;
1005 }
1006
1007 wxSize wxGnomePrintDC::GetPPI() const
1008 {
1009 return wxSize(72,72);
1010 }
1011
1012 void wxGnomePrintDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
1013 {
1014 m_signX = (xLeftRight ? 1 : -1);
1015 m_signY = (yBottomUp ? 1 : -1);
1016
1017 ComputeScaleAndOrigin();
1018 }
1019
1020 void wxGnomePrintDC::SetDeviceOrigin( wxCoord x, wxCoord y )
1021 {
1022 int h = 0;
1023 int w = 0;
1024 GetSize( &w, &h );
1025
1026 wxDC::SetDeviceOrigin( x, h-y );
1027 }
1028
1029 void wxGnomePrintDC::SetResolution(int ppi)
1030 {
1031 }
1032
1033 int wxGnomePrintDC::GetResolution()
1034 {
1035 return 72;
1036 }
1037
1038
1039 class wxGnomePrintModule: public wxModule
1040 {
1041 public:
1042 wxGnomePrintModule() {}
1043 bool OnInit() { wxPrintFactory::SetPrintFactory( new wxGnomePrintFactory ); return true; }
1044 void OnExit() { }
1045
1046 private:
1047 DECLARE_DYNAMIC_CLASS(wxGnomePrintModule)
1048 };
1049
1050 IMPLEMENT_DYNAMIC_CLASS(wxGnomePrintModule, wxModule)
1051
1052 #endif
1053 // wxUSE_LIBGNOMEPRINT