1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
4 * This file is part of GtkSourceView
6 * Derived from gedit-print.c
8 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
9 * Copyright (C) 2002 Paolo Maggi
10 * Copyright (C) 2003 Gustavo Giráldez
11 * Copyright (C) 2004 Red Hat, Inc.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330,
26 * Boston, MA 02111-1307, USA.
38 #include "gtksourceprintjob.h"
39 #include "image_viewer.h"
41 #include <glib/gi18n.h>
42 #include <gtk/gtkmain.h>
43 #include <gtk/gtktextview.h>
44 #include <libgnomeprint/gnome-print-pango.h>
59 #define DEFAULT_FONT_NAME "Monospace 10"
60 #define DEFAULT_COLOR 0x000000ff
62 #define CM(v) ((v) * 72.0 / 2.54)
63 #define A4_WIDTH (210.0 * 72 / 25.4)
64 #define A4_HEIGHT (297.0 * 72 / 25.4)
66 #define NUMBERS_TEXT_SEPARATION CM(0.5)
68 #define HEADER_FOOTER_SIZE 2.5
69 #define SEPARATOR_SPACING 1.5
70 #define SEPARATOR_LINE_WIDTH 1.0
73 typedef struct _TextSegment TextSegment;
74 typedef struct _Paragraph Paragraph;
75 typedef struct _TextStyle TextStyle;
77 /* a piece of text (within a paragraph) of the same style */
86 /* a printable line */
93 /* the style of a TextSegment */
96 PangoFontDescription *font_desc;
100 gboolean strikethrough;
101 PangoUnderline underline;
105 struct _GtkSourcePrintJobPrivate
107 /* General job configuration */
108 GnomePrintConfig *config;
109 GtkTextBuffer *buffer;
111 GtkWrapMode wrap_mode;
113 PangoLanguage *language;
114 PangoFontDescription *font;
115 PangoFontDescription *numbers_font;
118 gdouble margin_bottom;
120 gdouble margin_right;
122 /* Default header and footer configuration */
123 gboolean print_header;
124 gboolean print_footer;
125 PangoFontDescription *header_footer_font;
126 gchar *header_format_left;
127 gchar *header_format_center;
128 gchar *header_format_right;
129 gboolean header_separator;
130 gchar *footer_format_left;
131 gchar *footer_format_center;
132 gchar *footer_format_right;
133 gboolean footer_separator;
136 guint first_line_number;
137 guint last_line_number;
142 guint idle_printing_tag;
143 GnomePrintContext *print_ctxt;
144 GnomePrintJob *print_job;
145 PangoContext *pango_context;
146 PangoTabArray *tab_array;
149 gdouble available_height;
150 GSList *current_paragraph;
151 gint current_paragraph_line;
154 /* Cached information - all this information is obtained from
155 * other fields in the configuration */
156 GHashTable *tag_styles;
161 gdouble doc_margin_top;
162 gdouble doc_margin_left;
163 gdouble doc_margin_right;
164 gdouble doc_margin_bottom;
166 gdouble header_height;
167 gdouble footer_height;
168 gdouble numbers_width;
170 /* printable (for the document itself) size */
187 PROP_NUMBERS_FONT_DESC,
191 PROP_HEADER_FOOTER_FONT,
192 PROP_HEADER_FOOTER_FONT_DESC
202 static GObjectClass *parent_class = NULL;
203 static guint print_job_signals [LAST_SIGNAL] = { 0 };
205 static void gtk_source_print_job_class_init (GtkSourcePrintJobClass *klass);
206 static void gtk_source_print_job_instance_init (GtkSourcePrintJob *job);
207 static void gtk_source_print_job_finalize (GObject *object);
208 static void gtk_source_print_job_get_property (GObject *object,
212 static void gtk_source_print_job_set_property (GObject *object,
216 static void gtk_source_print_job_begin_page (GtkSourcePrintJob *job);
218 static void default_print_header (GtkSourcePrintJob *job,
221 static void default_print_footer (GtkSourcePrintJob *job,
227 gtk_source_print_job_get_type (void)
229 static GType our_type = 0;
233 static const GTypeInfo our_info = {
234 sizeof (GtkSourcePrintJobClass),
235 NULL, /* base_init */
236 NULL, /* base_finalize */
237 (GClassInitFunc) gtk_source_print_job_class_init,
238 NULL, /* class_finalize */
239 NULL, /* class_data */
240 sizeof (GtkSourcePrintJob),
242 (GInstanceInitFunc) gtk_source_print_job_instance_init
245 our_type = g_type_register_static (G_TYPE_OBJECT,
255 gtk_source_print_job_class_init (GtkSourcePrintJobClass *klass)
257 GObjectClass *object_class;
259 object_class = G_OBJECT_CLASS (klass);
260 parent_class = g_type_class_peek_parent (klass);
262 object_class->finalize = gtk_source_print_job_finalize;
263 object_class->get_property = gtk_source_print_job_get_property;
264 object_class->set_property = gtk_source_print_job_set_property;
266 klass->begin_page = gtk_source_print_job_begin_page;
267 klass->finished = NULL;
269 g_object_class_install_property (object_class,
271 g_param_spec_object ("config",
273 _("Configuration options for "
275 GNOME_TYPE_PRINT_CONFIG,
277 g_object_class_install_property (object_class,
279 g_param_spec_object ("buffer",
281 _("GtkTextBuffer object to print"),
282 GTK_TYPE_TEXT_BUFFER,
284 g_object_class_install_property (object_class,
286 g_param_spec_uint ("tabs_width",
288 _("Width in equivalent space "
289 "characters of tabs"),
292 g_object_class_install_property (object_class,
294 g_param_spec_enum ("wrap_mode",
296 _("Word wrapping mode"),
300 g_object_class_install_property (object_class,
302 g_param_spec_boolean ("highlight",
304 _("Whether to print the "
305 "document with highlighted "
309 g_object_class_install_property (object_class,
311 g_param_spec_string ("font",
313 _("GnomeFont name to use for the "
314 "document text (deprecated)"),
317 g_object_class_install_property (object_class,
319 g_param_spec_boxed ("font_desc",
320 _("Font Description"),
321 _("Font to use for the document text "
322 "(e.g. \"Monospace 10\")"),
323 PANGO_TYPE_FONT_DESCRIPTION,
325 g_object_class_install_property (object_class,
327 g_param_spec_string ("numbers_font",
329 _("GnomeFont name to use for the "
330 "line numbers (deprecated)"),
333 g_object_class_install_property (object_class,
334 PROP_NUMBERS_FONT_DESC,
335 g_param_spec_boxed ("numbers_font_desc",
337 _("Font description to use for the "
339 PANGO_TYPE_FONT_DESCRIPTION,
341 g_object_class_install_property (object_class,
343 g_param_spec_uint ("print_numbers",
344 _("Print Line Numbers"),
345 _("Interval of printed line numbers "
346 "(0 means no numbers)"),
349 g_object_class_install_property (object_class,
351 g_param_spec_boolean ("print_header",
353 _("Whether to print a header "
357 g_object_class_install_property (object_class,
359 g_param_spec_boolean ("print_footer",
361 _("Whether to print a footer "
365 g_object_class_install_property (object_class,
366 PROP_HEADER_FOOTER_FONT,
367 g_param_spec_string ("header_footer_font",
368 _("Header and Footer Font"),
369 _("GnomeFont name to use for the header "
370 "and footer (deprecated)"),
373 g_object_class_install_property (object_class,
374 PROP_HEADER_FOOTER_FONT_DESC,
375 g_param_spec_boxed ("header_footer_font_desc",
376 _("Header and Footer Font Description"),
377 _("Font to use for headers and footers "
378 "(e.g. \"Monospace 10\")"),
379 PANGO_TYPE_FONT_DESCRIPTION,
382 print_job_signals [BEGIN_PAGE] =
383 g_signal_new ("begin_page",
384 G_OBJECT_CLASS_TYPE (object_class),
386 G_STRUCT_OFFSET (GtkSourcePrintJobClass, begin_page),
388 g_cclosure_marshal_VOID__VOID,
391 print_job_signals [FINISHED] =
392 g_signal_new ("finished",
393 G_OBJECT_CLASS_TYPE (object_class),
395 G_STRUCT_OFFSET (GtkSourcePrintJobClass, finished),
397 g_cclosure_marshal_VOID__VOID,
403 gtk_source_print_job_instance_init (GtkSourcePrintJob *job)
405 GtkSourcePrintJobPrivate *priv;
407 priv = g_new0 (GtkSourcePrintJobPrivate, 1);
410 /* default job configuration */
414 priv->tabs_width = 8;
415 priv->wrap_mode = GTK_WRAP_NONE;
416 priv->highlight = TRUE;
417 priv->language = gtk_get_default_language ();
419 priv->numbers_font = NULL;
420 priv->print_numbers = 1;
421 priv->margin_top = 0.0;
422 priv->margin_bottom = 0.0;
423 priv->margin_left = 0.0;
424 priv->margin_right = 0.0;
426 priv->print_header = FALSE;
427 priv->print_footer = FALSE;
428 priv->header_footer_font = NULL;
429 priv->header_format_left = NULL;
430 priv->header_format_center = NULL;
431 priv->header_format_right = NULL;
432 priv->header_separator = FALSE;
433 priv->footer_format_left = NULL;
434 priv->footer_format_center = NULL;
435 priv->footer_format_right = NULL;
436 priv->footer_separator = FALSE;
439 priv->printing = FALSE;
440 priv->print_ctxt = NULL;
441 priv->print_job = NULL;
443 priv->page_count = 0;
445 priv->first_line_number = 0;
446 priv->paragraphs = NULL;
447 priv->tag_styles = NULL;
449 /* some default, sane values */
450 priv->page_width = A4_WIDTH;
451 priv->page_height = A4_HEIGHT;
452 priv->doc_margin_top = CM (1);
453 priv->doc_margin_left = CM (1);
454 priv->doc_margin_right = CM (1);
455 priv->doc_margin_bottom = CM (1);
459 free_paragraphs (GSList *paras)
461 while (paras != NULL)
463 Paragraph *para = paras->data;
464 TextSegment *seg = para->segment;
467 TextSegment *next = seg->next;
473 paras = g_slist_delete_link (paras, paras);
478 gtk_source_print_job_finalize (GObject *object)
480 GtkSourcePrintJob *job;
481 GtkSourcePrintJobPrivate *priv;
483 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (object));
485 job = GTK_SOURCE_PRINT_JOB (object);
490 if (priv->config != NULL)
491 gnome_print_config_unref (priv->config);
492 if (priv->buffer != NULL)
493 g_object_unref (priv->buffer);
494 if (priv->font != NULL)
495 pango_font_description_free (priv->font);
496 if (priv->numbers_font != NULL)
497 pango_font_description_free (priv->numbers_font);
498 if (priv->header_footer_font != NULL)
499 pango_font_description_free (priv->header_footer_font);
500 g_free (priv->header_format_left);
501 g_free (priv->header_format_right);
502 g_free (priv->header_format_center);
503 g_free (priv->footer_format_left);
504 g_free (priv->footer_format_right);
505 g_free (priv->footer_format_center);
507 if (priv->print_ctxt != NULL)
508 g_object_unref (priv->print_ctxt);
509 if (priv->print_job != NULL)
510 g_object_unref (priv->print_job);
511 if (priv->pango_context != NULL)
512 g_object_unref (priv->pango_context);
513 if (priv->tab_array != NULL)
514 pango_tab_array_free (priv->tab_array);
516 if (priv->paragraphs != NULL)
517 free_paragraphs (priv->paragraphs);
518 if (priv->tag_styles != NULL)
519 g_hash_table_destroy (priv->tag_styles);
525 G_OBJECT_CLASS (parent_class)->finalize (object);
529 gtk_source_print_job_get_property (GObject *object,
534 GtkSourcePrintJob *job = GTK_SOURCE_PRINT_JOB (object);
539 g_value_set_object (value, job->priv->config);
543 g_value_set_object (value, job->priv->buffer);
546 case PROP_TABS_WIDTH:
547 g_value_set_uint (value, job->priv->tabs_width);
551 g_value_set_enum (value, job->priv->wrap_mode);
555 g_value_set_boolean (value, job->priv->highlight);
559 g_value_take_string (value, gtk_source_print_job_get_font (job));
563 g_value_set_boxed (value, gtk_source_print_job_get_font_desc (job));
566 case PROP_NUMBERS_FONT:
567 g_value_take_string (value, gtk_source_print_job_get_numbers_font (job));
570 case PROP_NUMBERS_FONT_DESC:
571 g_value_set_boxed (value, gtk_source_print_job_get_numbers_font_desc (job));
574 case PROP_PRINT_NUMBERS:
575 g_value_set_uint (value, job->priv->print_numbers);
578 case PROP_PRINT_HEADER:
579 g_value_set_boolean (value, job->priv->print_header);
582 case PROP_PRINT_FOOTER:
583 g_value_set_boolean (value, job->priv->print_footer);
586 case PROP_HEADER_FOOTER_FONT:
587 g_value_take_string (value,
588 gtk_source_print_job_get_header_footer_font (job));
591 case PROP_HEADER_FOOTER_FONT_DESC:
592 g_value_set_boxed (value,
593 gtk_source_print_job_get_header_footer_font_desc (job));
597 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
603 gtk_source_print_job_set_property (GObject *object,
608 GtkSourcePrintJob *job = GTK_SOURCE_PRINT_JOB (object);
613 gtk_source_print_job_set_config (job, g_value_get_object (value));
617 gtk_source_print_job_set_buffer (job, g_value_get_object (value));
620 case PROP_TABS_WIDTH:
621 gtk_source_print_job_set_tabs_width (job, g_value_get_uint (value));
625 gtk_source_print_job_set_wrap_mode (job, g_value_get_enum (value));
629 gtk_source_print_job_set_highlight (job, g_value_get_boolean (value));
633 gtk_source_print_job_set_font (job, g_value_get_string (value));
637 gtk_source_print_job_set_font_desc (job, g_value_get_boxed (value));
640 case PROP_NUMBERS_FONT:
641 gtk_source_print_job_set_numbers_font (job, g_value_get_string (value));
644 case PROP_NUMBERS_FONT_DESC:
645 gtk_source_print_job_set_numbers_font_desc (job, g_value_get_boxed (value));
648 case PROP_PRINT_NUMBERS:
649 gtk_source_print_job_set_print_numbers (job, g_value_get_uint (value));
652 case PROP_PRINT_HEADER:
653 gtk_source_print_job_set_print_header (job, g_value_get_boolean (value));
656 case PROP_PRINT_FOOTER:
657 gtk_source_print_job_set_print_footer (job, g_value_get_boolean (value));
660 case PROP_HEADER_FOOTER_FONT:
661 gtk_source_print_job_set_header_footer_font (job,
662 g_value_get_string (value));
665 case PROP_HEADER_FOOTER_FONT_DESC:
666 gtk_source_print_job_set_header_footer_font_desc (job,
667 g_value_get_boxed (value));
671 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
677 gtk_source_print_job_begin_page (GtkSourcePrintJob *job)
679 g_return_if_fail (job->priv->printing);
681 if (job->priv->print_header && job->priv->header_height > 0)
685 x = job->priv->doc_margin_left + job->priv->margin_left;
686 y = job->priv->page_height - job->priv->doc_margin_top - job->priv->margin_top;
687 default_print_header (job, x, y);
690 if (job->priv->print_footer && job->priv->footer_height > 0)
694 x = job->priv->doc_margin_left + job->priv->margin_left;
695 y = job->priv->doc_margin_bottom +
696 job->priv->margin_bottom +
697 job->priv->footer_height;
698 default_print_footer (job, x, y);
702 /* ---- gnome-print / Pango convenience functions */
704 /* Gets the width of a layout in gnome-print coordinates */
706 get_layout_width (PangoLayout *layout)
710 pango_layout_get_size (layout, &layout_width, NULL);
711 return (gdouble) layout_width / PANGO_SCALE;
714 /* Gets the ascent/descent of a font in gnome-print coordinates */
716 get_font_ascent_descent (GtkSourcePrintJob *job,
717 PangoFontDescription *desc,
721 PangoFontMetrics *metrics;
723 metrics = pango_context_get_metrics (job->priv->pango_context,
725 job->priv->language);
728 *ascent = (gdouble) pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
730 *descent = (gdouble) pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
732 pango_font_metrics_unref (metrics);
735 /* Draws the first line in a layout; we use this for one-line layouts
736 * to get baseline alignment */
738 show_first_layout_line (GnomePrintContext *print_ctxt,
741 PangoLayoutLine *line;
743 line = pango_layout_get_lines (layout)->data;
744 gnome_print_pango_layout_line (print_ctxt, line);
748 get_line_number_layout (GtkSourcePrintJob *job,
754 num_str = g_strdup_printf ("%d", line_number);
755 layout = pango_layout_new (job->priv->pango_context);
756 pango_layout_set_font_description (layout, job->priv->numbers_font);
757 pango_layout_set_text (layout, num_str, -1);
763 /* ---- Configuration functions */
766 ensure_print_config (GtkSourcePrintJob *job)
768 if (job->priv->config == NULL)
769 job->priv->config = gnome_print_config_default ();
770 if (job->priv->font == NULL)
771 job->priv->font = pango_font_description_from_string (DEFAULT_FONT_NAME);
775 update_page_size_and_margins (GtkSourcePrintJob *job)
778 gdouble ascent, descent;
780 gnome_print_job_get_page_size_from_config (job->priv->config,
781 &job->priv->page_width,
782 &job->priv->page_height);
784 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_TOP,
785 &job->priv->doc_margin_top, NULL);
786 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM,
787 &job->priv->doc_margin_bottom, NULL);
788 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_LEFT,
789 &job->priv->doc_margin_left, NULL);
790 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT,
791 &job->priv->doc_margin_right, NULL);
793 /* set default fonts for numbers and header/footer */
794 if (job->priv->numbers_font == NULL)
795 job->priv->numbers_font = pango_font_description_copy (job->priv->font);
797 if (job->priv->header_footer_font == NULL)
798 job->priv->header_footer_font = pango_font_description_copy (job->priv->font);
800 /* calculate numbers width */
801 if (job->priv->print_numbers > 0)
803 layout = get_line_number_layout (job, job->priv->last_line_number);
804 job->priv->numbers_width = get_layout_width (layout) + NUMBERS_TEXT_SEPARATION;
805 g_object_unref (layout);
808 job->priv->numbers_width = 0.0;
810 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
812 /* calculate header/footer height */
813 if (job->priv->print_header &&
814 (job->priv->header_format_left != NULL ||
815 job->priv->header_format_center != NULL ||
816 job->priv->header_format_right != NULL))
817 job->priv->header_height = HEADER_FOOTER_SIZE * (ascent + descent);
819 job->priv->header_height = 0.0;
821 if (job->priv->print_footer &&
822 (job->priv->footer_format_left != NULL ||
823 job->priv->footer_format_center != NULL ||
824 job->priv->footer_format_right != NULL))
825 job->priv->footer_height = HEADER_FOOTER_SIZE * (ascent + descent);
827 job->priv->footer_height = 0.0;
829 /* verify that the user provided margins are not too excesive
830 * and that we still have room for the text */
831 job->priv->text_width = (job->priv->page_width -
832 job->priv->doc_margin_left - job->priv->doc_margin_right -
833 job->priv->margin_left - job->priv->margin_right -
834 job->priv->numbers_width);
836 job->priv->text_height = (job->priv->page_height -
837 job->priv->doc_margin_top - job->priv->doc_margin_bottom -
838 job->priv->margin_top - job->priv->margin_bottom -
839 job->priv->header_height - job->priv->footer_height);
841 /* FIXME: put some saner values than 5cm - Gustavo */
842 g_return_val_if_fail (job->priv->text_width > CM(5.0), FALSE);
843 g_return_val_if_fail (job->priv->text_height > CM(5.0), FALSE);
848 /* We want a uniform tab width for the entire job without regard to style
849 * See comments in gtksourceview.c:calculate_real_tab_width
852 calculate_real_tab_width (GtkSourcePrintJob *job, guint tab_size, gchar c)
861 tab_string = g_strnfill (tab_size, c);
862 layout = pango_layout_new (job->priv->pango_context);
863 pango_layout_set_text (layout, tab_string, -1);
866 pango_layout_get_size (layout, &tab_width, NULL);
867 g_object_unref (G_OBJECT (layout));
873 setup_pango_context (GtkSourcePrintJob *job)
875 PangoFontMap *font_map;
878 if (!job->priv->pango_context)
880 font_map = gnome_print_pango_get_default_font_map ();
881 job->priv->pango_context = gnome_print_pango_create_context (font_map);
884 pango_context_set_language (job->priv->pango_context, job->priv->language);
885 pango_context_set_font_description (job->priv->pango_context, job->priv->font);
887 if (job->priv->tab_array)
889 pango_tab_array_free (job->priv->tab_array);
890 job->priv->tab_array = NULL;
893 real_tab_width = calculate_real_tab_width (job, job->priv->tabs_width, ' ');
894 if (real_tab_width > 0)
896 job->priv->tab_array = pango_tab_array_new (1, FALSE);
897 pango_tab_array_set_tab (job->priv->tab_array, 0, PANGO_TAB_LEFT, real_tab_width);
903 /* ----- Helper functions */
906 font_description_to_gnome_font_name (PangoFontDescription *desc)
908 GnomeFontFace *font_face;
911 /* Will always return some font */
912 font_face = gnome_font_face_find_closest_from_pango_description (desc);
914 retval = g_strdup_printf("%s %f",
915 gnome_font_face_get_name (font_face),
916 (double) pango_font_description_get_size (desc) / PANGO_SCALE);
917 g_object_unref (font_face);
923 * The following routines are duplicated in gedit/gedit/gedit-prefs-manager.c
926 /* Do this ourselves since gnome_font_find_closest() doesn't call
927 * gnome_font_face_find_closest() (probably a gnome-print bug)
930 face_and_size_from_full_name (const guchar *name,
931 GnomeFontFace **face,
937 copy = g_strdup (name);
938 str_size = strrchr (copy, ' ');
943 *size = atof (str_size);
950 *face = gnome_font_face_find_closest (copy);
954 static PangoFontDescription *
955 font_description_from_gnome_font_name (const char *font_name)
958 PangoFontDescription *desc;
963 face_and_size_from_full_name (font_name, &face, &size);
965 /* Pango and GnomePrint have basically the same numeric weight values */
966 weight = (PangoWeight) gnome_font_face_get_weight_code (face);
967 style = gnome_font_face_is_italic (face) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL;
969 desc = pango_font_description_new ();
970 pango_font_description_set_family (desc, gnome_font_face_get_family_name (face));
971 pango_font_description_set_weight (desc, weight);
972 pango_font_description_set_style (desc, style);
973 pango_font_description_set_size (desc, size * PANGO_SCALE);
975 g_object_unref (face);
980 /* ---- TextStyle functions */
983 text_style_new (GtkSourcePrintJob *job, GtkTextTag *tag)
986 gboolean bg_set, fg_set;
988 g_return_val_if_fail (tag != NULL && GTK_IS_TEXT_TAG (tag), NULL);
990 style = g_new0 (TextStyle, 1);
992 g_object_get (G_OBJECT (tag),
993 "background_set", &bg_set,
994 "foreground_set", &fg_set,
995 "font_desc", &style->font_desc,
996 "scale", &style->scale,
997 "underline", &style->underline,
998 "strikethrough", &style->strikethrough,
1002 g_object_get (G_OBJECT (tag), "foreground_gdk", &style->foreground, NULL);
1005 g_object_get (G_OBJECT (tag), "background_gdk", &style->background, NULL);
1011 text_style_free (TextStyle *style)
1013 pango_font_description_free (style->font_desc);
1014 if (style->foreground)
1015 gdk_color_free (style->foreground);
1016 if (style->background)
1017 gdk_color_free (style->background);
1022 get_style (GtkSourcePrintJob *job, const GtkTextIter *iter)
1025 GtkTextTag *tag = NULL;
1026 TextStyle *style = NULL;
1028 if (job->priv->tag_styles == NULL)
1030 job->priv->tag_styles = g_hash_table_new_full (
1031 g_direct_hash, g_direct_equal,
1032 NULL, (GDestroyNotify) text_style_free);
1035 /* get the tags at iter */
1036 tags = gtk_text_iter_get_tags (iter);
1038 /* now find the GtkSourceTag (if any) which applies at iter */
1039 /* FIXME: this makes the assumption that the style at a given
1040 * iter is only determined by one GtkSourceTag (the one with
1041 * highest priority). This is true for now, but could change
1042 * in the future - Gustavo */
1046 if (GTK_IS_TEXT_TAG (t->data))
1048 t = g_slist_next (t);
1050 g_slist_free (tags);
1052 /* now we lookup the tag style in the cache */
1055 style = g_hash_table_lookup (job->priv->tag_styles, tag);
1058 /* create a style for the tag and cache it */
1059 style = text_style_new (job, tag);
1060 g_hash_table_insert (job->priv->tag_styles, tag, style);
1067 /* ----- Text fetching functions */
1070 get_text_simple (GtkSourcePrintJob *job,
1076 while (gtk_text_iter_compare (start, end) < 0)
1081 /* get a line of text */
1083 if (!gtk_text_iter_ends_line (&iter))
1084 gtk_text_iter_forward_to_line_end (&iter);
1086 if (gtk_text_iter_compare (&iter, end) > 0)
1090 seg = g_new0 (TextSegment, 1);
1091 seg->next = NULL; /* only one segment per line, since there's no style change */
1092 seg->style = NULL; /* use default style */
1093 /* FIXME: handle invisible text properly. This also
1094 * assumes the text has no embedded images and
1096 seg->text = gtk_text_iter_get_slice (start, &iter);
1098 para = g_new0 (Paragraph, 1);
1099 para->segment = seg;
1101 /* add the line of text to the job */
1102 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1104 gtk_text_iter_forward_line (&iter);
1106 /* advance to next line */
1109 job->priv->paragraphs = g_slist_reverse (job->priv->paragraphs);
1115 get_text_with_style (GtkSourcePrintJob *job,
1119 GtkTextIter limit, next_toggle;
1120 gboolean have_toggle;
1121 GdkPixbuf *image = NULL;
1123 /* make sure the region to print is highlighted */
1124 /*_gtk_source_buffer_highlight_region (job->priv->buffer, start, end, TRUE); */
1126 next_toggle = *start;
1127 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1129 /* FIXME: handle invisible text properly. This also assumes
1130 * the text has no embedded images and stuff */
1131 while (gtk_text_iter_compare (start, end) < 0)
1137 para = g_new0 (Paragraph, 1);
1139 /* get the style at the start of the line */
1140 style = get_style (job, start);
1142 /* get a line of text - limit points to the end of the line */
1144 if (!gtk_text_iter_ends_line (&limit))
1145 gtk_text_iter_forward_to_line_end (&limit);
1147 if (gtk_text_iter_compare (&limit, end) > 0)
1150 /* create the first segment for the line */
1151 para->segment = seg = g_new0 (TextSegment, 1);
1154 /* while the next tag toggle is within the line, we check to see
1155 * if the style has changed at each tag toggle position, and if so,
1156 * create new segments */
1157 while (have_toggle && gtk_text_iter_compare (&next_toggle, &limit) < 0)
1159 /* check style changes */
1160 style = get_style (job, &next_toggle);
1161 if (style != seg->style)
1163 TextSegment *new_seg;
1164 /* style has changed, thus we need to
1165 * create a new segment */
1166 /* close the current segment */
1167 seg->text = gtk_text_iter_get_slice (start, &next_toggle);
1168 if ((image = gtk_text_iter_get_pixbuf(start)) != NULL)
1171 *start = next_toggle;
1173 new_seg = g_new0 (TextSegment, 1);
1174 seg->next = new_seg;
1179 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1182 /* close the line */
1184 seg->text = gtk_text_iter_get_slice (start, &limit);
1185 if ((image = gtk_text_iter_get_pixbuf(start)) != NULL)
1188 /* add the line of text to the job */
1189 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1191 /* advance to next line */
1193 gtk_text_iter_forward_line (start);
1195 if (gtk_text_iter_compare (&next_toggle, start) < 0) {
1196 next_toggle = *start;
1197 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1200 job->priv->paragraphs = g_slist_reverse (job->priv->paragraphs);
1206 get_text_to_print (GtkSourcePrintJob *job,
1207 const GtkTextIter *start,
1208 const GtkTextIter *end)
1210 GtkTextIter _start, _end;
1213 g_return_val_if_fail (start != NULL && end != NULL, FALSE);
1214 g_return_val_if_fail (job->priv->buffer != NULL, FALSE);
1219 /* erase any previous data */
1220 if (job->priv->paragraphs != NULL)
1222 free_paragraphs (job->priv->paragraphs);
1223 job->priv->paragraphs = NULL;
1225 if (job->priv->tag_styles != NULL)
1227 g_hash_table_destroy (job->priv->tag_styles);
1228 job->priv->tag_styles = NULL;
1231 /* provide ordered iters */
1232 gtk_text_iter_order (&_start, &_end);
1234 /* save the first and last line numbers for future reference */
1235 job->priv->first_line_number = gtk_text_iter_get_line (&_start) + 1;
1236 job->priv->last_line_number = gtk_text_iter_get_line (&_end) + 1;
1238 if (!job->priv->highlight)
1239 retval = get_text_simple (job, &_start, &_end);
1241 retval = get_text_with_style (job, &_start, &_end);
1243 if (retval && job->priv->paragraphs == NULL)
1248 /* add an empty line to allow printing empty documents */
1249 seg = g_new0 (TextSegment, 1);
1251 seg->style = NULL; /* use default style */
1252 seg->text = g_strdup ("");
1254 para = g_new0 (Paragraph, 1);
1255 para->segment = seg;
1257 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1263 /* ----- Pagination functions */
1266 add_attribute_to_list (PangoAttribute *attr,
1267 PangoAttrList *list,
1271 attr->start_index = index;
1272 attr->end_index = index + len;
1273 pango_attr_list_insert (list, attr);
1277 create_layout_for_para (GtkSourcePrintJob *job,
1282 PangoLayout *layout;
1283 PangoAttrList *attrs;
1286 GdkPixbuf *image = NULL;
1287 text = g_string_new (NULL);
1288 attrs = pango_attr_list_new ();
1290 seg = para->segment;
1295 gsize seg_len = strlen (seg->text);
1296 g_string_append (text, seg->text);
1300 PangoAttribute *attr;
1302 attr = pango_attr_font_desc_new (seg->style->font_desc);
1303 add_attribute_to_list (attr, attrs, index, seg_len);
1305 if (seg->style->scale != PANGO_SCALE_MEDIUM)
1307 attr = pango_attr_scale_new (seg->style->scale);
1308 add_attribute_to_list (attr, attrs, index, seg_len);
1311 if (seg->style->foreground)
1313 attr = pango_attr_foreground_new (seg->style->foreground->red,
1314 seg->style->foreground->green,
1315 seg->style->foreground->blue);
1316 add_attribute_to_list (attr, attrs, index, seg_len);
1319 if (seg->style->background)
1321 attr = pango_attr_background_new (seg->style->background->red,
1322 seg->style->background->green,
1323 seg->style->background->blue);
1324 add_attribute_to_list (attr, attrs, index, seg_len);
1327 if (seg->style->strikethrough)
1329 attr = pango_attr_strikethrough_new (TRUE);
1330 add_attribute_to_list (attr, attrs, index, seg_len);
1333 if (seg->style->underline != PANGO_UNDERLINE_NONE)
1335 attr = pango_attr_underline_new (seg->style->underline);
1336 add_attribute_to_list (attr, attrs, index, seg_len);
1348 layout = pango_layout_new (job->priv->pango_context);
1350 pango_layout_set_width (layout, job->priv->text_width * PANGO_SCALE);
1352 switch (job->priv->wrap_mode) {
1354 pango_layout_set_wrap (layout, PANGO_WRAP_CHAR);
1357 pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
1359 case GTK_WRAP_WORD_CHAR:
1360 pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
1364 * Ellipsize the paragraph when text wrapping is disabled.
1365 * Another possibility would be to set the width so the text
1366 * breaks into multiple lines, and paginate/render just the
1368 * See also Comment #23 by Owen on bug #143874.
1371 /* orph says to comment this out and commit it.
1372 PANGO_ELLIPSIZE_END is not available in pango
1373 1.4.1, at least, and he says this code is never
1375 /*pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);*/
1380 if (job->priv->tab_array)
1381 pango_layout_set_tabs (layout, job->priv->tab_array);
1383 if (image == NULL) {
1384 pango_layout_set_text (layout, text->str, text->len);
1385 pango_layout_set_attributes (layout, attrs);
1388 pango_layout_set_text(layout, "IMAGE\n", 6);
1390 pango_attr_list_unref(attrs);
1391 g_string_free(text, TRUE);
1396 /* FIXME: <horrible-hack>
1397 * For empty paragraphs, pango_layout_iter_get_baseline() returns 0,
1398 * so I check this condition and add a space character to force
1399 * the calculation of the baseline. I don't like that, but I
1400 * didn't find a better way to do it. Note that a paragraph is
1401 * considered empty either when it has no characters, or when
1403 * See comment #22 and #23 on bug #143874.
1405 if (job->priv->print_numbers > 0)
1407 PangoLayoutIter *iter;
1408 iter = pango_layout_get_iter (layout);
1409 if (pango_layout_iter_get_baseline (iter) == 0)
1411 g_string_append_c (text, ' ');
1412 pango_layout_set_text (layout, text->str, text->len);
1414 pango_layout_iter_free (iter);
1416 /* FIXME: </horrible-hack> */
1418 g_string_free (text, TRUE);
1419 pango_attr_list_unref (attrs);
1424 /* The break logic in this function needs to match that in print_paragraph */
1426 paginate_paragraph (GtkSourcePrintJob *job,
1429 PangoLayout *layout;
1430 PangoLayoutIter *iter;
1431 PangoRectangle logical_rect;
1436 gboolean is_image = FALSE;
1438 tmp = create_layout_for_para (job, para, &is_image);
1440 layout = (PangoLayout *)tmp;
1443 image = (GdkPixbuf *)tmp;
1447 if (image == NULL) {
1448 iter = pango_layout_get_iter (layout);
1455 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
1456 max = (gdouble) (logical_rect.y + logical_rect.height) / PANGO_SCALE;
1458 if (max - page_skip > job->priv->available_height)
1460 /* "create" a new page */
1461 job->priv->page_count++;
1462 job->priv->available_height = job->priv->text_height;
1463 page_skip = (gdouble) logical_rect.y / PANGO_SCALE;
1467 while (pango_layout_iter_next_line (iter));
1469 job->priv->available_height -= max - page_skip;
1471 pango_layout_iter_free (iter);
1472 g_object_unref (layout);
1474 gint max_height = job->priv->available_height;
1475 gint image_height = gdk_pixbuf_get_height(image);
1476 gint image_width = gdk_pixbuf_get_width(image);
1477 gint scaled_height = 0, scaled_width = 0;
1478 image_viewer_get_resized_size(image_width,
1480 job->priv->text_width,
1481 job->priv->text_height,
1482 &scaled_width, &scaled_height);
1484 if (scaled_height > max_height) {
1485 job->priv->page_count++;
1486 job->priv->available_height = job->priv->text_height;
1488 job->priv->available_height -= scaled_height;
1495 paginate_text (GtkSourcePrintJob *job)
1500 /* set these to zero so the first break_line creates a new page */
1501 job->priv->page_count = 0;
1502 job->priv->available_height = 0;
1503 line_number = job->priv->first_line_number;
1504 l = job->priv->paragraphs;
1507 Paragraph *para = l->data;
1509 para->line_number = line_number;
1510 paginate_paragraph (job, para);
1513 l = g_slist_next (l);
1516 /* FIXME: do we have any error condition which can force us to
1517 * return %FALSE? - Gustavo */
1521 /* ---- Printing functions */
1524 begin_page (GtkSourcePrintJob *job)
1526 gnome_print_beginpage (job->priv->print_ctxt, NULL);
1528 g_signal_emit (job, print_job_signals [BEGIN_PAGE], 0);
1532 end_page (GtkSourcePrintJob *job)
1534 gnome_print_showpage (job->priv->print_ctxt);
1538 print_line_number (GtkSourcePrintJob *job,
1543 PangoLayout *layout;
1545 layout = get_line_number_layout (job, line_number);
1547 x = x + job->priv->numbers_width - get_layout_width (layout) - NUMBERS_TEXT_SEPARATION;
1548 gnome_print_moveto (job->priv->print_ctxt, x, y);
1550 show_first_layout_line (job->priv->print_ctxt, layout);
1552 g_object_unref (layout);
1555 /* The break logic in this function needs to match that in paginate_paragraph
1557 * @start_line is the first line in the paragraph to print
1558 * @y is updated to the position after the portion of the paragraph we printed
1559 * @baseline_out is set to the baseline of the first line of the paragraph
1560 * if we printed it. (And not set otherwise)
1562 * Returns the first unprinted line in the paragraph (unprinted because it
1563 * flowed onto the next page) or -1 if the entire paragraph was printed.
1566 print_paragraph (GtkSourcePrintJob *job,
1571 gdouble *baseline_out,
1574 PangoLayout *layout;
1575 PangoLayoutIter *iter;
1576 PangoRectangle logical_rect;
1586 tmp = create_layout_for_para (job, para, &is_image);
1588 layout = (PangoLayout *)tmp;
1591 image = (GdkPixbuf *)tmp;
1596 iter = pango_layout_get_iter (layout);
1598 /* Skip over lines already printed on previous page(s) */
1599 for (current_line = 0; current_line < start_line; current_line++)
1600 pango_layout_iter_next_line (iter);
1607 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
1608 max = (gdouble) (logical_rect.y + logical_rect.height) / PANGO_SCALE;
1610 if (current_line == start_line)
1611 page_skip = (gdouble) logical_rect.y / PANGO_SCALE;
1613 if (max - page_skip > job->priv->available_height)
1615 result = current_line; /* Save position for next page */
1619 baseline = (gdouble) pango_layout_iter_get_baseline (iter) / PANGO_SCALE;
1620 baseline = *y + page_skip - baseline; /* Adjust to global coordinates */
1621 if (current_line == 0)
1622 *baseline_out = baseline;
1624 gnome_print_moveto (job->priv->print_ctxt,
1625 x + (gdouble) logical_rect.x / PANGO_SCALE,
1627 gnome_print_pango_layout_line (job->priv->print_ctxt,
1628 pango_layout_iter_get_line (iter));
1632 while (pango_layout_iter_next_line (iter));
1634 job->priv->available_height -= max - page_skip;
1635 *y -= max - page_skip;
1637 pango_layout_iter_free (iter);
1638 g_object_unref (layout);
1640 gint max_height = job->priv->available_height;
1641 gint image_height = gdk_pixbuf_get_height(image);
1642 gint image_width = gdk_pixbuf_get_width(image);
1643 gint scaled_height = 0, scaled_width = 0;
1644 GdkPixbuf *scaled_image = NULL;
1645 image_viewer_get_resized_size(image_width,
1647 job->priv->text_width,
1648 job->priv->text_height,
1649 &scaled_width, &scaled_height);
1651 if (scaled_height > max_height) {
1655 scaled_image = gdk_pixbuf_scale_simple
1656 (image, scaled_width, scaled_height,
1657 GDK_INTERP_BILINEAR);
1659 gnome_print_moveto(job->priv->print_ctxt,
1661 gnome_print_gsave(job->priv->print_ctxt);
1662 gnome_print_translate(job->priv->print_ctxt,
1663 x, *y - scaled_height);
1664 gnome_print_scale(job->priv->print_ctxt,
1668 if (gdk_pixbuf_get_has_alpha(image))
1669 gnome_print_rgbaimage (job->priv->print_ctxt,
1670 gdk_pixbuf_get_pixels (scaled_image),
1671 gdk_pixbuf_get_width (scaled_image),
1672 gdk_pixbuf_get_height (scaled_image),
1673 gdk_pixbuf_get_rowstride (scaled_image));
1675 gnome_print_rgbimage (job->priv->print_ctxt,
1676 gdk_pixbuf_get_pixels (scaled_image),
1677 gdk_pixbuf_get_width (scaled_image),
1678 gdk_pixbuf_get_height (scaled_image),
1679 gdk_pixbuf_get_rowstride (scaled_image));
1680 g_object_unref(scaled_image);
1681 gnome_print_grestore(job->priv->print_ctxt);
1683 job->priv->available_height -= scaled_height;
1684 *y -= scaled_height;
1693 print_page (GtkSourcePrintJob *job)
1698 gboolean force_fit = TRUE;
1704 job->priv->available_height = job->priv->text_height;
1706 y = job->priv->page_height -
1707 job->priv->doc_margin_top - job->priv->margin_top -
1708 job->priv->header_height;
1709 x = job->priv->doc_margin_left + job->priv->margin_left +
1710 job->priv->numbers_width;
1711 l = job->priv->current_paragraph;
1712 line = job->priv->current_paragraph_line;
1716 Paragraph *para = l->data;
1718 gint last_line = line;
1720 line = print_paragraph (job, para, line, x, &y, &baseline, force_fit);
1722 if (last_line == 0 && line != 0)
1724 /* We printed the first line of a paragraph */
1725 if (job->priv->print_numbers > 0 &&
1726 ((para->line_number % job->priv->print_numbers) == 0))
1727 print_line_number (job,
1729 job->priv->doc_margin_left +
1730 job->priv->margin_left,
1733 job->priv->printed_lines++;
1737 break; /* Didn't all fit on this page */
1744 job->priv->current_paragraph = l;
1745 job->priv->current_paragraph_line = line;
1749 setup_for_print (GtkSourcePrintJob *job)
1751 job->priv->current_paragraph = job->priv->paragraphs;
1752 job->priv->page = 0;
1753 job->priv->printed_lines = 0;
1755 if (job->priv->print_job != NULL)
1756 g_object_unref (job->priv->print_job);
1757 if (job->priv->print_ctxt != NULL)
1758 g_object_unref (job->priv->print_ctxt);
1760 job->priv->print_job = gnome_print_job_new (job->priv->config);
1761 job->priv->print_ctxt = gnome_print_job_get_context (job->priv->print_job);
1763 gnome_print_pango_update_context (job->priv->pango_context, job->priv->print_ctxt);
1767 print_job (GtkSourcePrintJob *job)
1769 while (job->priv->current_paragraph != NULL)
1772 gnome_print_job_close (job->priv->print_job);
1776 idle_printing_handler (GtkSourcePrintJob *job)
1778 g_assert (job->priv->current_paragraph != NULL);
1782 if (job->priv->current_paragraph == NULL)
1784 gnome_print_job_close (job->priv->print_job);
1785 job->priv->printing = FALSE;
1786 job->priv->idle_printing_tag = 0;
1788 g_signal_emit (job, print_job_signals [FINISHED], 0);
1789 /* after this the print job object is possibly
1790 * destroyed (common use case) */
1798 /* Public API ------------------- */
1801 * gtk_source_print_job_new:
1802 * @config: an optional #GnomePrintConfig object.
1804 * Creates a new print job object, initially setting the print configuration.
1806 * Return value: the new print job object.
1809 gtk_source_print_job_new (GnomePrintConfig *config)
1811 GtkSourcePrintJob *job;
1813 g_return_val_if_fail (config == NULL || GNOME_IS_PRINT_CONFIG (config), NULL);
1815 job = GTK_SOURCE_PRINT_JOB (g_object_new (GTK_TYPE_SOURCE_PRINT_JOB, NULL));
1817 gtk_source_print_job_set_config (job, config);
1823 * gtk_source_print_job_new_with_buffer:
1824 * @config: an optional #GnomePrintConfig.
1825 * @buffer: the #GtkTextBuffer to print (might be %NULL).
1827 * Creates a new print job to print @buffer.
1829 * Return value: a new print job object.
1832 gtk_source_print_job_new_with_buffer (GnomePrintConfig *config,
1833 GtkTextBuffer *buffer)
1835 GtkSourcePrintJob *job;
1837 g_return_val_if_fail (config == NULL || GNOME_IS_PRINT_CONFIG (config), NULL);
1838 g_return_val_if_fail (buffer == NULL || GTK_IS_TEXT_BUFFER (buffer), NULL);
1840 job = gtk_source_print_job_new (config);
1842 gtk_source_print_job_set_buffer (job, buffer);
1847 /* --- print job basic configuration */
1850 * gtk_source_print_job_set_config:
1851 * @job: a #GtkSourcePrintJob.
1852 * @config: a #GnomePrintConfig object to get printing configuration from.
1854 * Sets the print configuration for the job. If you don't set a
1855 * configuration object for the print job, when needed one will be
1856 * created with gnome_print_config_default().
1859 gtk_source_print_job_set_config (GtkSourcePrintJob *job,
1860 GnomePrintConfig *config)
1862 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1863 g_return_if_fail (GNOME_IS_PRINT_CONFIG (config));
1864 g_return_if_fail (!job->priv->printing);
1866 if (config == job->priv->config)
1869 if (job->priv->config != NULL)
1870 gnome_print_config_unref (job->priv->config);
1872 job->priv->config = config;
1873 gnome_print_config_ref (config);
1875 g_object_notify (G_OBJECT (job), "config");
1879 * gtk_source_print_job_get_config:
1880 * @job: a #GtkSourcePrintJob.
1882 * Gets the current #GnomePrintConfig the print job will use. If not
1883 * previously set, this will create a default configuration and return
1884 * it. The returned object reference is owned by the print job.
1886 * Return value: the #GnomePrintConfig for the print job.
1889 gtk_source_print_job_get_config (GtkSourcePrintJob *job)
1891 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
1893 ensure_print_config (job);
1895 return job->priv->config;
1899 * gtk_source_print_job_set_buffer:
1900 * @job: a #GtkSourcePrintJob.
1901 * @buffer: a #GtkTextBuffer.
1903 * Sets the #GtkTextBuffer the print job will print. You need to
1904 * specify a buffer to print, either by the use of this function or by
1905 * creating the print job with gtk_source_print_job_new_with_buffer().
1908 gtk_source_print_job_set_buffer (GtkSourcePrintJob *job,
1909 GtkTextBuffer *buffer)
1911 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1912 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1913 g_return_if_fail (!job->priv->printing);
1915 if (buffer == job->priv->buffer)
1918 if (job->priv->buffer != NULL)
1919 g_object_unref (job->priv->buffer);
1921 job->priv->buffer = buffer;
1922 g_object_ref (buffer);
1924 g_object_notify (G_OBJECT (job), "buffer");
1928 * gtk_source_print_job_get_buffer:
1929 * @job: a #GtkSourcePrintJob.
1931 * Gets the #GtkTextBuffer the print job would print. The returned
1932 * object reference (if non %NULL) is owned by the job object and
1933 * should not be unreferenced.
1935 * Return value: the #GtkTextBuffer to print.
1938 gtk_source_print_job_get_buffer (GtkSourcePrintJob *job)
1940 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
1942 return job->priv->buffer;
1945 /* --- print job layout and style configuration */
1948 * gtk_source_print_job_set_tabs_width:
1949 * @job: a #GtkSourcePrintJob.
1950 * @tabs_width: the number of equivalent spaces for a tabulation.
1952 * Sets the width (in equivalent spaces) of tabulations for the
1953 * printed text. The width in printing units will be calculated as
1954 * the width of a string containing @tabs_width spaces of the default
1955 * font. Tabulation stops are set for the full width of printed text.
1958 gtk_source_print_job_set_tabs_width (GtkSourcePrintJob *job,
1961 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1962 g_return_if_fail (!job->priv->printing);
1964 if (tabs_width == job->priv->tabs_width)
1967 job->priv->tabs_width = tabs_width;
1969 g_object_notify (G_OBJECT (job), "tabs_width");
1973 * gtk_source_print_job_get_tabs_width:
1974 * @job: a #GtkSourcePrintJob.
1976 * Determines the configured width (in equivalent spaces) of
1977 * tabulations. The default value is 8.
1979 * Return value: the width (in equivalent spaces) of a tabulation.
1982 gtk_source_print_job_get_tabs_width (GtkSourcePrintJob *job)
1984 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
1986 return job->priv->tabs_width;
1990 * gtk_source_print_job_set_wrap_mode:
1991 * @job: a #GtkSourcePrintJob.
1992 * @wrap: the wrap mode.
1994 * Sets the wrap mode for lines of text larger than the printable
1995 * width. See #GtkWrapMode for a definition of the possible values.
1998 gtk_source_print_job_set_wrap_mode (GtkSourcePrintJob *job,
2001 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2002 g_return_if_fail (!job->priv->printing);
2004 if (wrap == job->priv->wrap_mode)
2007 job->priv->wrap_mode = wrap;
2009 g_object_notify (G_OBJECT (job), "wrap_mode");
2013 * gtk_source_print_job_get_wrap_mode:
2014 * @job: a #GtkSourcePrintJob.
2016 * Determines the wrapping style for text lines wider than the
2017 * printable width. The default is no wrapping.
2019 * Return value: the current wrapping mode for the print job.
2022 gtk_source_print_job_get_wrap_mode (GtkSourcePrintJob *job)
2024 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), GTK_WRAP_NONE);
2026 return job->priv->wrap_mode;
2030 * gtk_source_print_job_set_highlight:
2031 * @job: a #GtkSourcePrintJob.
2032 * @highlight: %TRUE if the printed text should be highlighted.
2034 * Sets whether the printed text will be highlighted according to the
2035 * buffer rules. Both color and font style are applied.
2038 gtk_source_print_job_set_highlight (GtkSourcePrintJob *job,
2041 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2042 g_return_if_fail (!job->priv->printing);
2044 highlight = (highlight != FALSE);
2046 if (highlight == job->priv->highlight)
2049 job->priv->highlight = highlight;
2051 g_object_notify (G_OBJECT (job), "highlight");
2055 * gtk_source_print_job_get_highlight:
2056 * @job: a #GtkSourcePrintJob.
2058 * Determines if the job is configured to print the text highlighted
2059 * with colors and font styles. Note that highlighting will happen
2060 * only if the buffer to print has highlighting activated.
2062 * Return value: %TRUE if the printed output will be highlighted.
2065 gtk_source_print_job_get_highlight (GtkSourcePrintJob *job)
2067 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2069 return job->priv->highlight;
2073 * gtk_source_print_job_set_font_desc:
2074 * @job: a #GtkSourcePrintJob.
2075 * @desc: the #PangoFontDescription for the default font
2077 * Sets the default font for the printed text.
2080 gtk_source_print_job_set_font_desc (GtkSourcePrintJob *job,
2081 PangoFontDescription *desc)
2083 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2084 g_return_if_fail (desc != NULL);
2085 g_return_if_fail (!job->priv->printing);
2087 desc = pango_font_description_copy (desc);
2088 if (job->priv->font != NULL)
2089 pango_font_description_free (job->priv->font);
2090 job->priv->font = desc;
2091 g_object_freeze_notify (G_OBJECT (job));
2092 g_object_notify (G_OBJECT (job), "font");
2093 g_object_notify (G_OBJECT (job), "font_desc");
2094 g_object_thaw_notify (G_OBJECT (job));
2098 * gtk_source_print_job_set_font:
2099 * @job: a #GtkSourcePrintJob.
2100 * @font_name: the name of the default font.
2102 * Sets the default font for the printed text. @font_name should be a
2103 * <emphasis>full font name</emphasis> GnomePrint can understand
2104 * (e.g. "Monospace Regular 10.0").
2106 * Note that @font_name is a #GnomeFont name not a Pango font
2107 * description string. This function is deprecated since #GnomeFont is
2108 * no longer used when implementing printing for GtkSourceView; you
2109 * should use gtk_source_print_job_set_font_desc() instead.
2112 gtk_source_print_job_set_font (GtkSourcePrintJob *job,
2113 const gchar *font_name)
2115 PangoFontDescription *desc;
2117 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2118 g_return_if_fail (font_name != NULL);
2119 g_return_if_fail (!job->priv->printing);
2121 desc = font_description_from_gnome_font_name (font_name);
2124 gtk_source_print_job_set_font_desc (job, desc);
2125 pango_font_description_free (desc);
2130 * gtk_source_print_job_get_font_desc:
2131 * @job: a #GtkSourcePrintJob.
2133 * Determines the default font to be used for the printed text. The
2134 * returned string is of the form "Fontfamily Style Size",
2135 * for example "Monospace Regular 10.0". The returned value
2136 * should be freed when no longer needed.
2138 * Return value: the current text font description. This value is
2139 * owned by the job and must not be modified or freed.
2141 PangoFontDescription *
2142 gtk_source_print_job_get_font_desc (GtkSourcePrintJob *job)
2144 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2146 ensure_print_config (job);
2148 return job->priv->font;
2152 * gtk_source_print_job_get_font:
2153 * @job: a #GtkSourcePrintJob.
2155 * Determines the default font to be used for the printed text. The
2156 * returned string is of the form "Fontfamily Style Size",
2157 * for example "Monospace Regular 10.0". The returned value
2158 * should be freed when no longer needed.
2160 * Note that the result is a #GnomeFont name not a Pango font
2161 * description string. This function is deprecated since #GnomeFont is
2162 * no longer used when implementing printing for GtkSourceView; you
2163 * should use gtk_source_print_job_get_font_desc() instead.
2165 * Return value: a newly allocated string with the name of the current
2169 gtk_source_print_job_get_font (GtkSourcePrintJob *job)
2171 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2173 ensure_print_config (job);
2175 return font_description_to_gnome_font_name (job->priv->font);
2179 * gtk_source_print_job_setup_from_view:
2180 * @job: a #GtkSourcePrintJob.
2181 * @view: a #GtkSourceView to get configuration from.
2183 * Convenience function to set several configuration options at once,
2184 * so that the printed output matches @view. The options set are
2185 * buffer (if not set already), tabs width, highlighting, wrap mode
2189 gtk_source_print_job_setup_from_view (GtkSourcePrintJob *job,
2192 GtkTextBuffer *buffer = NULL;
2193 PangoContext *pango_context;
2195 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2196 g_return_if_fail (!job->priv->printing);
2198 buffer = gtk_text_view_get_buffer (view);
2200 if (job->priv->buffer == NULL && buffer != NULL)
2201 gtk_source_print_job_set_buffer (job, buffer);
2203 /* gtk_source_print_job_set_tabs_width (job, gtk_source_view_get_tabs_width (view)); */
2204 gtk_source_print_job_set_highlight (job, TRUE);
2205 gtk_source_print_job_set_wrap_mode (job, gtk_text_view_get_wrap_mode (view));
2207 pango_context = gtk_widget_get_pango_context (GTK_WIDGET (view));
2208 gtk_source_print_job_set_font_desc (job,
2209 pango_context_get_font_description (pango_context));
2213 * gtk_source_print_job_set_numbers_font_desc:
2214 * @job: a #GtkSourcePrintJob.
2215 * @desc: the #PangoFontDescription for the font for line numbers, or %NULL
2217 * Sets the font for printing line numbers on the left margin. If
2218 * NULL is supplied, the default font (i.e. the one being used for the
2219 * text) will be used instead.
2222 gtk_source_print_job_set_numbers_font_desc (GtkSourcePrintJob *job,
2223 PangoFontDescription *desc)
2225 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2226 g_return_if_fail (!job->priv->printing);
2229 desc = pango_font_description_copy (desc);
2230 if (job->priv->numbers_font != NULL)
2231 pango_font_description_free (job->priv->numbers_font);
2232 job->priv->numbers_font = desc;
2233 g_object_freeze_notify (G_OBJECT (job));
2234 g_object_notify (G_OBJECT (job), "numbers_font");
2235 g_object_notify (G_OBJECT (job), "numbers_font_desc");
2236 g_object_thaw_notify (G_OBJECT (job));
2240 * gtk_source_print_job_set_numbers_font:
2241 * @job: a #GtkSourcePrintJob.
2242 * @font_name: the full name of the font for line numbers, or %NULL.
2244 * Sets the font for printing line numbers on the left margin. If
2245 * %NULL is supplied, the default font (i.e. the one being used for the
2246 * text) will be used instead.
2248 * Note that @font_name is a #GnomeFont name not a Pango font
2249 * description string. This function is deprecated since #GnomeFont is
2250 * no longer used when implementing printing for GtkSourceView; you
2251 * should use gtk_source_print_job_set_numbers_font_desc() instead.
2254 gtk_source_print_job_set_numbers_font (GtkSourcePrintJob *job,
2255 const gchar *font_name)
2257 PangoFontDescription *desc;
2259 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2260 g_return_if_fail (!job->priv->printing);
2262 if (font_name != NULL)
2264 desc = font_description_from_gnome_font_name (font_name);
2267 gtk_source_print_job_set_numbers_font_desc (job, desc);
2268 pango_font_description_free (desc);
2272 gtk_source_print_job_set_numbers_font (job, NULL);
2276 * gtk_source_print_job_get_numbers_font_desc:
2277 * @job: a #GtkSourcePrintJob.
2279 * Determines the font to be used for the line numbers. This function
2280 * might return %NULL if a specific font for numbers has not been set.
2282 * Return value: the line numbers font description or %NULL. This value is
2283 * owned by the job and must not be modified or freed.
2285 PangoFontDescription *
2286 gtk_source_print_job_get_numbers_font_desc (GtkSourcePrintJob *job)
2288 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2290 return job->priv->numbers_font;
2294 * gtk_source_print_job_get_numbers_font:
2295 * @job: a #GtkSourcePrintJob.
2297 * Determines the font to be used for the line numbers. The returned
2298 * string is of the form "Fontfamily Style Size", for
2299 * example "Monospace Regular 10.0". The returned value
2300 * should be freed when no longer needed. This function might return
2301 * %NULL if a specific font for numbers has not been set.
2303 * Note that the result is a #GnomeFont name not a Pango font
2304 * description string. This function is deprecated since #GnomeFont is
2305 * no longer used when implementing printing for GtkSourceView; you
2306 * should use gtk_source_print_job_get_numbers_font_desc() instead.
2308 * Return value: a newly allocated string with the name of the current
2309 * line numbers font, or %NULL.
2312 gtk_source_print_job_get_numbers_font (GtkSourcePrintJob *job)
2314 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2316 if (job->priv->numbers_font != NULL)
2317 return font_description_to_gnome_font_name (job->priv->numbers_font);
2323 * gtk_source_print_job_set_print_numbers:
2324 * @job: a #GtkSourcePrintJob.
2325 * @interval: interval for printed line numbers.
2327 * Sets the interval for printed line numbers. If @interval is 0 no
2328 * numbers will be printed. If greater than 0, a number will be
2329 * printed every @interval lines (i.e. 1 will print all line numbers).
2332 gtk_source_print_job_set_print_numbers (GtkSourcePrintJob *job,
2335 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2336 g_return_if_fail (!job->priv->printing);
2338 if (interval == job->priv->print_numbers)
2341 job->priv->print_numbers = interval;
2343 g_object_notify (G_OBJECT (job), "print_numbers");
2347 * gtk_source_print_job_get_print_numbers:
2348 * @job: a #GtkSourcePrintJob.
2350 * Determines the interval used for line number printing. If the
2351 * value is 0, no line numbers will be printed. The default value is
2352 * 1 (i.e. numbers printed in all lines).
2354 * Return value: the interval of printed line numbers.
2357 gtk_source_print_job_get_print_numbers (GtkSourcePrintJob *job)
2359 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2361 return job->priv->print_numbers;
2365 * gtk_source_print_job_set_text_margins:
2366 * @job: a #GtkSourcePrintJob.
2367 * @top: the top user margin.
2368 * @bottom: the bottom user margin.
2369 * @left: the left user margin.
2370 * @right: the right user margin.
2372 * Sets the four user margins for the print job. These margins are in
2373 * addition to the document margins provided in the #GnomePrintConfig
2374 * and will not be used for headers, footers or line numbers (those
2375 * are calculated separatedly). You can print in the space allocated
2376 * by these margins by connecting to the <link
2377 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link> signal. The
2378 * space is around the printed text, and inside the margins specified
2379 * in the #GnomePrintConfig.
2381 * The margin numbers are given in device units. If any of the given
2382 * values is less than 0, that particular margin is not altered by
2386 gtk_source_print_job_set_text_margins (GtkSourcePrintJob *job,
2392 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2393 g_return_if_fail (!job->priv->printing);
2396 job->priv->margin_top = top;
2398 job->priv->margin_bottom = bottom;
2400 job->priv->margin_left = left;
2402 job->priv->margin_right = right;
2406 * gtk_source_print_job_get_text_margins:
2407 * @job: a #GtkSourcePrintJob.
2408 * @top: a pointer to a #gdouble to return the top margin.
2409 * @bottom: a pointer to a #gdouble to return the bottom margin.
2410 * @left: a pointer to a #gdouble to return the left margin.
2411 * @right: a pointer to a #gdouble to return the right margin.
2413 * Determines the user set margins for the job. This function
2414 * retrieves the values previously set by
2415 * gtk_source_print_job_set_text_margins(). The default for all four
2416 * margins is 0. Any of the pointers can be %NULL if you want to
2417 * ignore that value.
2420 gtk_source_print_job_get_text_margins (GtkSourcePrintJob *job,
2426 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2429 *top = job->priv->margin_top;
2431 *bottom = job->priv->margin_bottom;
2433 *left = job->priv->margin_left;
2435 *right = job->priv->margin_right;
2438 /* --- printing operations */
2441 gtk_source_print_job_prepare (GtkSourcePrintJob *job,
2442 const GtkTextIter *start,
2443 const GtkTextIter *end)
2445 PROFILE (GTimer *timer);
2447 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2448 g_return_val_if_fail (!job->priv->printing, FALSE);
2449 g_return_val_if_fail (job->priv->buffer != NULL, FALSE);
2450 g_return_val_if_fail (start != NULL && end != NULL, FALSE);
2452 /* make sure we have a sane configuration to start printing */
2453 ensure_print_config (job);
2455 PROFILE (timer = g_timer_new ());
2457 /* get the text to print */
2458 if (!get_text_to_print (job, start, end))
2461 PROFILE (g_message ("get_text_to_print: %.2f", g_timer_elapsed (timer, NULL)));
2463 if (!setup_pango_context (job))
2467 if (!update_page_size_and_margins (job))
2470 /* split the document in pages */
2471 if (!paginate_text (job))
2475 g_message ("paginate_text: %.2f", g_timer_elapsed (timer, NULL));
2476 g_timer_destroy (timer);
2483 * gtk_source_print_job_print:
2484 * @job: a configured #GtkSourcePrintJob.
2486 * Produces a #GnomePrintJob with the printed document. The whole
2487 * contents of the configured #GtkTextBuffer are printed. The
2488 * returned job is already closed and ready to be previewed (using
2489 * gnome_print_job_preview_new()) or printed directly. The caller of
2490 * this function owns a reference to the returned object, so @job can
2491 * be destroyed and the output will still be valid, or the document
2492 * can be printed again with different settings.
2494 * Return value: a closed #GnomePrintJob with the printed document, or
2495 * %NULL if printing could not be completed.
2498 gtk_source_print_job_print (GtkSourcePrintJob *job)
2500 GtkTextIter start, end;
2502 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2503 g_return_val_if_fail (!job->priv->printing, NULL);
2504 g_return_val_if_fail (job->priv->buffer != NULL, NULL);
2506 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (job->priv->buffer), &start, &end);
2508 return gtk_source_print_job_print_range (job, &start, &end);
2512 * gtk_source_print_job_print_range:
2513 * @job: a configured #GtkSourcePrintJob.
2514 * @start: the start of the region of text to print.
2515 * @end: the end of the region of text to print.
2517 * Similar to gtk_source_print_job_print(), except you can specify a
2518 * range of text to print. The passed #GtkTextIter values might be
2521 * Return value: a closed #GnomePrintJob with the text from @start to
2522 * @end printed, or %NULL if @job could not print.
2525 gtk_source_print_job_print_range (GtkSourcePrintJob *job,
2526 const GtkTextIter *start,
2527 const GtkTextIter *end)
2529 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2530 g_return_val_if_fail (!job->priv->printing, NULL);
2531 g_return_val_if_fail (job->priv->buffer != NULL, NULL);
2532 g_return_val_if_fail (start != NULL && end != NULL, NULL);
2533 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
2534 GTK_TEXT_BUFFER (job->priv->buffer) &&
2535 gtk_text_iter_get_buffer (end) ==
2536 GTK_TEXT_BUFFER (job->priv->buffer), NULL);
2538 if (!gtk_source_print_job_prepare (job, start, end))
2541 /* real work starts here */
2542 setup_for_print (job);
2544 job->priv->printing = TRUE;
2546 job->priv->printing = FALSE;
2548 g_object_ref (job->priv->print_job);
2549 return job->priv->print_job;
2552 /* --- asynchronous printing */
2555 * gtk_source_print_job_print_range_async:
2556 * @job: a configured #GtkSourcePrintJob.
2557 * @start: the start of the region of text to print.
2558 * @end: the end of the region of text to print.
2560 * Starts to print @job asynchronously. This function will ready the
2561 * @job for printing and install an idle handler that will render one
2564 * This function will not return immediatly, as only page rendering is
2565 * done asynchronously. Text retrieval and paginating happens within
2566 * this function. Also, if highlighting is enabled, the whole buffer
2567 * needs to be highlighted first.
2569 * To get notification when the job has finished, you must connect to
2571 * linkend="GtkSourcePrintJob-finished">"finished"</link>
2572 * signal. After this signal is emitted you can retrieve the
2573 * resulting #GnomePrintJob with gtk_source_print_job_get_print_job().
2574 * You may cancel the job with gtk_source_print_job_cancel().
2576 * Return value: %TRUE if the print started.
2579 gtk_source_print_job_print_range_async (GtkSourcePrintJob *job,
2580 const GtkTextIter *start,
2581 const GtkTextIter *end)
2583 GSource *idle_source;
2585 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2586 g_return_val_if_fail (!job->priv->printing, FALSE);
2587 g_return_val_if_fail (job->priv->buffer != NULL, FALSE);
2588 g_return_val_if_fail (start != NULL && end != NULL, FALSE);
2589 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
2590 GTK_TEXT_BUFFER (job->priv->buffer) &&
2591 gtk_text_iter_get_buffer (end) ==
2592 GTK_TEXT_BUFFER (job->priv->buffer), FALSE);
2594 if (!gtk_source_print_job_prepare (job, start, end))
2597 /* real work starts here */
2598 setup_for_print (job);
2599 if (job->priv->current_paragraph == NULL)
2602 /* setup the idle handler to print each page at a time */
2603 idle_source = g_idle_source_new ();
2604 g_source_set_priority (idle_source, GTK_SOURCE_PRINT_JOB_PRIORITY);
2605 g_source_set_closure (idle_source,
2606 g_cclosure_new_object ((GCallback) idle_printing_handler,
2608 job->priv->idle_printing_tag = g_source_attach (idle_source, NULL);
2609 g_source_unref (idle_source);
2611 job->priv->printing = TRUE;
2617 * gtk_source_print_job_cancel:
2618 * @job: a #GtkSourcePrintJob.
2620 * Cancels an asynchronous printing operation. This will remove any
2621 * pending print idle handler and unref the current #GnomePrintJob.
2623 * Note that if you got a reference to the job's #GnomePrintJob (using
2624 * gtk_source_print_job_get_print_job()) it will not be destroyed
2625 * (since you hold a reference to it), but it will not be closed
2626 * either. If you wish to show or print the partially printed
2627 * document you need to close it yourself.
2629 * This function has no effect when called from a non-asynchronous
2633 gtk_source_print_job_cancel (GtkSourcePrintJob *job)
2635 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2636 g_return_if_fail (job->priv->printing);
2638 if (job->priv->idle_printing_tag > 0)
2640 g_source_remove (job->priv->idle_printing_tag);
2641 job->priv->current_paragraph = NULL;
2642 job->priv->idle_printing_tag = 0;
2643 job->priv->printing = FALSE;
2644 g_object_unref (job->priv->print_job);
2645 g_object_unref (job->priv->print_ctxt);
2646 job->priv->print_job = NULL;
2647 job->priv->print_ctxt = NULL;
2652 * gtk_source_print_job_get_print_job:
2653 * @job: a #GtkSourcePrintJob.
2655 * Gets a reference to the #GnomePrintJob which the @job is printing
2656 * or has recently finished printing. You need to unref the returned
2659 * You may call this function in the middle of an asynchronous
2660 * printing operation, but the returned #GnomePrintJob will not be
2661 * closed until the last page is printed and the <link
2662 * linkend="GtkSourcePrintJob-finished">"finished"</link>
2663 * signal is emitted.
2665 * Return value: a new reference to the @job's #GnomePrintJob, or
2669 gtk_source_print_job_get_print_job (GtkSourcePrintJob *job)
2671 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2673 if (job->priv->print_job)
2674 g_object_ref (job->priv->print_job);
2676 return job->priv->print_job;
2679 /* --- information for asynchronous ops and headers and footers callback */
2682 * gtk_source_print_job_get_page:
2683 * @job: a #GtkSourcePrintJob.
2685 * Determines the currently printing page number. This function is
2686 * only valid while printing (either synchronously or asynchronously).
2688 * Return value: the current page number.
2691 gtk_source_print_job_get_page (GtkSourcePrintJob *job)
2693 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2694 g_return_val_if_fail (job->priv->printing, 0);
2696 return job->priv->page;
2700 * gtk_source_print_job_get_page_count:
2701 * @job: a #GtkSourcePrintJob.
2703 * Determines the total number of pages the job will print. The
2704 * returned value is only meaninful after pagination has finished. In
2705 * practice, for synchronous printing this means when <link
2706 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link>
2707 * is emitted, or after gtk_source_print_job_print_range_async() has
2710 * Return value: the number of pages of the printed job.
2713 gtk_source_print_job_get_page_count (GtkSourcePrintJob *job)
2715 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2717 return job->priv->page_count;
2721 * gtk_source_print_job_get_print_context:
2722 * @job: a printing #GtkSourcePrintJob.
2724 * Determines the #GnomePrintContext of the current job. This
2725 * function is only valid while printing. Normally you would use this
2726 * function to print in the margins set by
2727 * gtk_source_print_job_set_margins() in a handler for the <link
2728 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link>
2731 * Return value: the current #GnomePrintContext. The returned object
2735 gtk_source_print_job_get_print_context (GtkSourcePrintJob *job)
2737 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2738 g_return_val_if_fail (job->priv->printing, NULL);
2740 return job->priv->print_ctxt;
2743 /* ---- Header and footer (default implementation) */
2745 /* Most of this code taken from GLib's g_date_strftime() in gdate.c
2746 * GLIB - Library of useful routines for C programming
2747 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald */
2750 strdup_strftime (const gchar *format, const struct tm *tm)
2752 gsize locale_format_len = 0;
2753 gchar *locale_format;
2759 GError *error = NULL;
2761 g_return_val_if_fail (format != NULL, NULL);
2762 g_return_val_if_fail (tm != NULL, NULL);
2764 locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);
2768 g_warning (G_STRLOC "Error converting format to locale encoding: %s",
2770 g_error_free (error);
2775 tmpbufsize = MAX (128, locale_format_len * 2);
2778 tmpbuf = g_malloc (tmpbufsize);
2780 /* Set the first byte to something other than '\0', to be able to
2781 * recognize whether strftime actually failed or just returned "".
2784 tmplen = strftime (tmpbuf, tmpbufsize, locale_format, tm);
2786 if (tmplen == 0 && tmpbuf[0] != '\0')
2791 if (tmpbufsize > 65536)
2793 g_warning (G_STRLOC "Maximum buffer size for strdup_strftime "
2794 "exceeded: giving up");
2795 g_free (locale_format);
2802 g_free (locale_format);
2804 convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);
2809 g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s",
2811 g_error_free (error);
2820 evaluate_format_string (GtkSourcePrintJob *job, const gchar *format)
2823 gchar *eval_str, *retval;
2824 const struct tm *tm;
2830 tm = localtime (&now);
2832 /* analyze format string and replace the codes we know */
2833 eval = g_string_new_len (NULL, strlen (format));
2834 ch = g_utf8_get_char (format);
2839 format = g_utf8_next_char (format);
2840 ch = g_utf8_get_char (format);
2842 g_string_append_printf (eval, "%d", job->priv->page);
2844 g_string_append_printf (eval, "%d", job->priv->page_count);
2847 g_string_append_c (eval, '%');
2848 g_string_append_unichar (eval, ch);
2852 g_string_append_unichar (eval, ch);
2854 format = g_utf8_next_char (format);
2855 ch = g_utf8_get_char (format);
2858 eval_str = g_string_free (eval, FALSE);
2859 retval = strdup_strftime (eval_str, tm);
2866 print_header_footer_string (GtkSourcePrintJob *job,
2867 const gchar *format,
2872 PangoLayout *layout;
2877 width = job->priv->text_width + job->priv->numbers_width;
2879 text = evaluate_format_string (job, format);
2882 layout = pango_layout_new (job->priv->pango_context);
2883 pango_layout_set_font_description (layout, job->priv->header_footer_font);
2884 pango_layout_set_text (layout, text, -1);
2886 xx = x + x_align * (width - get_layout_width (layout));
2887 gnome_print_moveto (job->priv->print_ctxt, xx, y);
2888 show_first_layout_line (job->priv->print_ctxt, layout);
2891 g_object_unref (layout);
2896 default_print_header (GtkSourcePrintJob *job,
2902 gdouble ascent, descent;
2904 width = job->priv->text_width + job->priv->numbers_width;
2906 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
2911 if (job->priv->header_format_left != NULL)
2912 print_header_footer_string (job, job->priv->header_format_left, 0.0, x, yy);
2915 if (job->priv->header_format_right != NULL)
2916 print_header_footer_string (job, job->priv->header_format_right, 1.0, x, yy);
2919 if (job->priv->header_format_center != NULL)
2920 print_header_footer_string (job, job->priv->header_format_center, 0.5, x, yy);
2923 if (job->priv->header_separator)
2925 yy = y - (SEPARATOR_SPACING * (ascent + descent));
2926 gnome_print_setlinewidth (job->priv->print_ctxt, SEPARATOR_LINE_WIDTH);
2927 gnome_print_moveto (job->priv->print_ctxt, x, yy);
2928 gnome_print_lineto (job->priv->print_ctxt, x + width, yy);
2929 gnome_print_stroke (job->priv->print_ctxt);
2934 default_print_footer (GtkSourcePrintJob *job,
2940 gdouble ascent, descent;
2942 width = job->priv->text_width + job->priv->numbers_width;
2944 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
2946 yy = y - job->priv->footer_height + descent;
2949 if (job->priv->footer_format_left != NULL)
2950 print_header_footer_string (job, job->priv->footer_format_left, 0.0, x, yy);
2953 if (job->priv->footer_format_right != NULL)
2954 print_header_footer_string (job, job->priv->footer_format_right, 1.0, x, yy);
2957 if (job->priv->footer_format_center != NULL)
2958 print_header_footer_string (job, job->priv->footer_format_center, 0.5, x, yy);
2961 if (job->priv->footer_separator)
2963 yy = y - job->priv->footer_height +
2964 (SEPARATOR_SPACING * (ascent + descent));
2965 gnome_print_setlinewidth (job->priv->print_ctxt, SEPARATOR_LINE_WIDTH);
2966 gnome_print_moveto (job->priv->print_ctxt, x, yy);
2967 gnome_print_lineto (job->priv->print_ctxt, x + width, yy);
2968 gnome_print_stroke (job->priv->print_ctxt);
2973 * gtk_source_print_job_set_print_header:
2974 * @job: a #GtkSourcePrintJob.
2975 * @setting: %TRUE if you want the header to be printed.
2977 * Sets whether you want to print a header in each page. The default
2978 * header consists of three pieces of text and an optional line
2979 * separator, configurable with
2980 * gtk_source_print_job_set_header_format().
2982 * Note that by default the header format is unspecified, and if it's
2983 * empty it will not be printed, regardless of this setting.
2986 gtk_source_print_job_set_print_header (GtkSourcePrintJob *job,
2989 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2990 g_return_if_fail (!job->priv->printing);
2992 setting = (setting != FALSE);
2994 if (setting == job->priv->print_header)
2997 job->priv->print_header = setting;
2999 g_object_notify (G_OBJECT (job), "print_header");
3003 * gtk_source_print_job_get_print_header:
3004 * @job: a #GtkSourcePrintJob.
3006 * Determines if a header is set to be printed for each page. A
3007 * header will be printed if this function returns %TRUE
3008 * <emphasis>and</emphasis> some format strings have been specified
3009 * with gtk_source_print_job_set_header_format().
3011 * Return value: %TRUE if the header is set to be printed.
3014 gtk_source_print_job_get_print_header (GtkSourcePrintJob *job)
3016 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
3018 return job->priv->print_header;
3022 * gtk_source_print_job_set_print_footer:
3023 * @job: a #GtkSourcePrintJob.
3024 * @setting: %TRUE if you want the footer to be printed.
3026 * Sets whether you want to print a footer in each page. The default
3027 * footer consists of three pieces of text and an optional line
3028 * separator, configurable with
3029 * gtk_source_print_job_set_footer_format().
3031 * Note that by default the footer format is unspecified, and if it's
3032 * empty it will not be printed, regardless of this setting.
3035 gtk_source_print_job_set_print_footer (GtkSourcePrintJob *job,
3038 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3039 g_return_if_fail (!job->priv->printing);
3041 setting = (setting != FALSE);
3043 if (setting == job->priv->print_footer)
3046 job->priv->print_footer = setting;
3048 g_object_notify (G_OBJECT (job), "print_footer");
3052 * gtk_source_print_job_get_print_footer:
3053 * @job: a #GtkSourcePrintJob.
3055 * Determines if a footer is set to be printed for each page. A
3056 * footer will be printed if this function returns %TRUE
3057 * <emphasis>and</emphasis> some format strings have been specified
3058 * with gtk_source_print_job_set_footer_format().
3060 * Return value: %TRUE if the footer is set to be printed.
3063 gtk_source_print_job_get_print_footer (GtkSourcePrintJob *job)
3065 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
3067 return job->priv->print_footer;
3071 * gtk_source_print_job_set_header_footer_font_desc:
3072 * @job: a #GtkSourcePrintJob.
3073 * @desc: the #PangoFontDescription for the font to be used in headers and footers, or %NULL.
3075 * Sets the font for printing headers and footers. If %NULL is
3076 * supplied, the default font (i.e. the one being used for the text)
3077 * will be used instead.
3080 gtk_source_print_job_set_header_footer_font_desc (GtkSourcePrintJob *job,
3081 PangoFontDescription *desc)
3083 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3084 g_return_if_fail (!job->priv->printing);
3087 desc = pango_font_description_copy (desc);
3088 if (job->priv->header_footer_font != NULL)
3089 pango_font_description_free (job->priv->header_footer_font);
3090 job->priv->header_footer_font = desc;
3091 g_object_freeze_notify (G_OBJECT (job));
3092 g_object_notify (G_OBJECT (job), "header_footer_font");
3093 g_object_notify (G_OBJECT (job), "header_footer_font_desc");
3094 g_object_thaw_notify (G_OBJECT (job));
3098 * gtk_source_print_job_set_header_footer_font:
3099 * @job: a #GtkSourcePrintJob.
3100 * @font_name: the full name of the font to be used in headers and footers, or %NULL.
3102 * Sets the font for printing headers and footers. If %NULL is
3103 * supplied, the default font (i.e. the one being used for the text)
3104 * will be used instead.
3106 * Note that @font_name is a #GnomeFont name not a Pango font
3107 * description string. This function is deprecated since #GnomeFont is
3108 * no longer used when implementing printing for GtkSourceView; you
3109 * should use gtk_source_print_job_set_header_footer_font_desc() instead.
3112 gtk_source_print_job_set_header_footer_font (GtkSourcePrintJob *job,
3113 const gchar *font_name)
3115 PangoFontDescription *desc;
3117 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3118 g_return_if_fail (!job->priv->printing);
3120 if (font_name != NULL)
3122 desc = font_description_from_gnome_font_name (font_name);
3125 gtk_source_print_job_set_header_footer_font_desc (job, desc);
3126 pango_font_description_free (desc);
3130 gtk_source_print_job_set_header_footer_font_desc (job, NULL);
3134 * gtk_source_print_job_get_header_footer_font_desc:
3135 * @job: a #GtkSourcePrintJob.
3137 * Determines the font to be used for the header and footer. This function
3138 * might return %NULL if a specific font has not been set.
3140 * Return value: the header and footer font description or %NULL. This value is
3141 * owned by the job and must not be modified or freed.
3143 PangoFontDescription *
3144 gtk_source_print_job_get_header_footer_font_desc (GtkSourcePrintJob *job)
3146 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
3148 return job->priv->header_footer_font;
3152 * gtk_source_print_job_get_header_footer_font:
3153 * @job: a #GtkSourcePrintJob.
3155 * Determines the font to be used for the header and footer. The
3156 * returned string is of the form "Fontfamily Style Size",
3157 * for example "Monospace Regular 10.0". The returned value
3158 * should be freed when no longer needed. This function might return
3159 * %NULL if a specific font has not been set.
3161 * Note that the result is a #GnomeFont name not a Pango font
3162 * description string. This function is deprecated since #GnomeFont is
3163 * no longer used when implementing printing for GtkSourceView; you
3164 * should use gtk_source_print_job_get_header_footer_font_desc() instead.
3166 * Return value: a newly allocated string with the name of the current
3167 * header and footer font, or %NULL.
3170 gtk_source_print_job_get_header_footer_font (GtkSourcePrintJob *job)
3172 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
3174 if (job->priv->header_footer_font != NULL)
3175 return font_description_to_gnome_font_name (job->priv->header_footer_font);
3181 * gtk_source_print_job_set_header_format:
3182 * @job: a #GtkSourcePrintJob.
3183 * @left: a format string to print on the left of the header.
3184 * @center: a format string to print on the center of the header.
3185 * @right: a format string to print on the right of the header.
3186 * @separator: %TRUE if you want a separator line to be printed.
3188 * Sets strftime like header format strings, to be printed on the
3189 * left, center and right of the top of each page. The strings may
3190 * include strftime(3) codes which will be expanded at print time.
3191 * All strftime() codes are accepted, with the addition of %N for the
3192 * page number and %Q for the page count.
3194 * @separator specifies if a solid line should be drawn to separate
3195 * the header from the document text.
3197 * If %NULL is given for any of the three arguments, that particular
3198 * string will not be printed. For the header to be printed, in
3199 * addition to specifying format strings, you need to enable header
3200 * printing with gtk_source_print_job_set_print_header().
3203 gtk_source_print_job_set_header_format (GtkSourcePrintJob *job,
3205 const gchar *center,
3209 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3210 g_return_if_fail (!job->priv->printing);
3212 /* FIXME: validate given strings? */
3213 g_free (job->priv->header_format_left);
3214 g_free (job->priv->header_format_center);
3215 g_free (job->priv->header_format_right);
3216 job->priv->header_format_left = g_strdup (left);
3217 job->priv->header_format_center = g_strdup (center);
3218 job->priv->header_format_right = g_strdup (right);
3219 job->priv->header_separator = separator;
3223 * gtk_source_print_job_set_footer_format:
3224 * @job: a #GtkSourcePrintJob.
3225 * @left: a format string to print on the left of the footer.
3226 * @center: a format string to print on the center of the footer.
3227 * @right: a format string to print on the right of the footer.
3228 * @separator: %TRUE if you want a separator line to be printed.
3230 * Like gtk_source_print_job_set_header_format(), but for the footer.
3233 gtk_source_print_job_set_footer_format (GtkSourcePrintJob *job,
3235 const gchar *center,
3239 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3240 g_return_if_fail (!job->priv->printing);
3242 /* FIXME: validate given strings? */
3243 g_free (job->priv->footer_format_left);
3244 g_free (job->priv->footer_format_center);
3245 g_free (job->priv->footer_format_right);
3246 job->priv->footer_format_left = g_strdup (left);
3247 job->priv->footer_format_center = g_strdup (center);
3248 job->priv->footer_format_right = g_strdup (right);
3249 job->priv->footer_separator = separator;