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