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 3 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, see <http://www.gnu.org/licenses/>.
36 #include "gtksourceprintjob.h"
37 #include "image_viewer.h"
39 #include <glib/gi18n.h>
41 #include <libgnomeprint/gnome-print-pango.h>
56 #define DEFAULT_FONT_NAME "Monospace 10"
57 #define DEFAULT_COLOR 0x000000ff
59 #define CM(v) ((v) * 72.0 / 2.54)
60 #define A4_WIDTH (210.0 * 72 / 25.4)
61 #define A4_HEIGHT (297.0 * 72 / 25.4)
63 #define NUMBERS_TEXT_SEPARATION CM(0.5)
65 #define HEADER_FOOTER_SIZE 2.5
66 #define SEPARATOR_SPACING 1.5
67 #define SEPARATOR_LINE_WIDTH 1.0
70 typedef struct _TextSegment TextSegment;
71 typedef struct _Paragraph Paragraph;
72 typedef struct _TextStyle TextStyle;
74 /* a piece of text (within a paragraph) of the same style */
83 /* a printable line */
90 /* the style of a TextSegment */
93 PangoFontDescription *font_desc;
97 gboolean strikethrough;
98 PangoUnderline underline;
102 struct _GtkSourcePrintJobPrivate
104 /* General job configuration */
105 GnomePrintConfig *config;
106 GtkTextBuffer *buffer;
108 GtkWrapMode wrap_mode;
110 PangoLanguage *language;
111 PangoFontDescription *font;
112 PangoFontDescription *numbers_font;
115 gdouble margin_bottom;
117 gdouble margin_right;
119 /* Default header and footer configuration */
120 gboolean print_header;
121 gboolean print_footer;
122 PangoFontDescription *header_footer_font;
123 gchar *header_format_left;
124 gchar *header_format_center;
125 gchar *header_format_right;
126 gboolean header_separator;
127 gchar *footer_format_left;
128 gchar *footer_format_center;
129 gchar *footer_format_right;
130 gboolean footer_separator;
133 guint first_line_number;
134 guint last_line_number;
139 guint idle_printing_tag;
140 GnomePrintContext *print_ctxt;
141 GnomePrintJob *print_job;
142 PangoContext *pango_context;
143 PangoTabArray *tab_array;
146 gdouble available_height;
147 GSList *current_paragraph;
148 gint current_paragraph_line;
151 /* Cached information - all this information is obtained from
152 * other fields in the configuration */
153 GHashTable *tag_styles;
158 gdouble doc_margin_top;
159 gdouble doc_margin_left;
160 gdouble doc_margin_right;
161 gdouble doc_margin_bottom;
163 gdouble header_height;
164 gdouble footer_height;
165 gdouble numbers_width;
167 /* printable (for the document itself) size */
184 PROP_NUMBERS_FONT_DESC,
188 PROP_HEADER_FOOTER_FONT,
189 PROP_HEADER_FOOTER_FONT_DESC
199 static GObjectClass *parent_class = NULL;
200 static guint print_job_signals [LAST_SIGNAL] = { 0 };
202 static void gtk_source_print_job_class_init (GtkSourcePrintJobClass *klass);
203 static void gtk_source_print_job_instance_init (GtkSourcePrintJob *job);
204 static void gtk_source_print_job_finalize (GObject *object);
205 static void gtk_source_print_job_get_property (GObject *object,
209 static void gtk_source_print_job_set_property (GObject *object,
213 static void gtk_source_print_job_begin_page (GtkSourcePrintJob *job);
215 static void default_print_header (GtkSourcePrintJob *job,
218 static void default_print_footer (GtkSourcePrintJob *job,
224 gtk_source_print_job_get_type (void)
226 static GType our_type = 0;
230 static const GTypeInfo our_info = {
231 sizeof (GtkSourcePrintJobClass),
232 NULL, /* base_init */
233 NULL, /* base_finalize */
234 (GClassInitFunc) gtk_source_print_job_class_init,
235 NULL, /* class_finalize */
236 NULL, /* class_data */
237 sizeof (GtkSourcePrintJob),
239 (GInstanceInitFunc) gtk_source_print_job_instance_init
242 our_type = g_type_register_static (G_TYPE_OBJECT,
252 gtk_source_print_job_class_init (GtkSourcePrintJobClass *klass)
254 GObjectClass *object_class;
256 object_class = G_OBJECT_CLASS (klass);
257 parent_class = g_type_class_peek_parent (klass);
259 object_class->finalize = gtk_source_print_job_finalize;
260 object_class->get_property = gtk_source_print_job_get_property;
261 object_class->set_property = gtk_source_print_job_set_property;
263 klass->begin_page = gtk_source_print_job_begin_page;
264 klass->finished = NULL;
266 g_object_class_install_property (object_class,
268 g_param_spec_object ("config",
270 _("Configuration options for "
272 GNOME_TYPE_PRINT_CONFIG,
274 g_object_class_install_property (object_class,
276 g_param_spec_object ("buffer",
278 _("GtkTextBuffer object to print"),
279 GTK_TYPE_TEXT_BUFFER,
281 g_object_class_install_property (object_class,
283 g_param_spec_uint ("tabs_width",
285 _("Width in equivalent space "
286 "characters of tabs"),
289 g_object_class_install_property (object_class,
291 g_param_spec_enum ("wrap_mode",
293 _("Word wrapping mode"),
297 g_object_class_install_property (object_class,
299 g_param_spec_boolean ("highlight",
301 _("Whether to print the "
302 "document with highlighted "
306 g_object_class_install_property (object_class,
308 g_param_spec_string ("font",
310 _("GnomeFont name to use for the "
311 "document text (deprecated)"),
314 g_object_class_install_property (object_class,
316 g_param_spec_boxed ("font_desc",
317 _("Font Description"),
318 _("Font to use for the document text "
319 "(e.g. \"Monospace 10\")"),
320 PANGO_TYPE_FONT_DESCRIPTION,
322 g_object_class_install_property (object_class,
324 g_param_spec_string ("numbers_font",
326 _("GnomeFont name to use for the "
327 "line numbers (deprecated)"),
330 g_object_class_install_property (object_class,
331 PROP_NUMBERS_FONT_DESC,
332 g_param_spec_boxed ("numbers_font_desc",
334 _("Font description to use for the "
336 PANGO_TYPE_FONT_DESCRIPTION,
338 g_object_class_install_property (object_class,
340 g_param_spec_uint ("print_numbers",
341 _("Print Line Numbers"),
342 _("Interval of printed line numbers "
343 "(0 means no numbers)"),
346 g_object_class_install_property (object_class,
348 g_param_spec_boolean ("print_header",
350 _("Whether to print a header "
354 g_object_class_install_property (object_class,
356 g_param_spec_boolean ("print_footer",
358 _("Whether to print a footer "
362 g_object_class_install_property (object_class,
363 PROP_HEADER_FOOTER_FONT,
364 g_param_spec_string ("header_footer_font",
365 _("Header and Footer Font"),
366 _("GnomeFont name to use for the header "
367 "and footer (deprecated)"),
370 g_object_class_install_property (object_class,
371 PROP_HEADER_FOOTER_FONT_DESC,
372 g_param_spec_boxed ("header_footer_font_desc",
373 _("Header and Footer Font Description"),
374 _("Font to use for headers and footers "
375 "(e.g. \"Monospace 10\")"),
376 PANGO_TYPE_FONT_DESCRIPTION,
379 print_job_signals [BEGIN_PAGE] =
380 g_signal_new ("begin_page",
381 G_OBJECT_CLASS_TYPE (object_class),
383 G_STRUCT_OFFSET (GtkSourcePrintJobClass, begin_page),
385 g_cclosure_marshal_VOID__VOID,
388 print_job_signals [FINISHED] =
389 g_signal_new ("finished",
390 G_OBJECT_CLASS_TYPE (object_class),
392 G_STRUCT_OFFSET (GtkSourcePrintJobClass, finished),
394 g_cclosure_marshal_VOID__VOID,
400 gtk_source_print_job_instance_init (GtkSourcePrintJob *job)
402 GtkSourcePrintJobPrivate *priv;
404 priv = g_new0 (GtkSourcePrintJobPrivate, 1);
407 /* default job configuration */
411 priv->tabs_width = 8;
412 priv->wrap_mode = GTK_WRAP_NONE;
413 priv->highlight = TRUE;
414 priv->language = gtk_get_default_language ();
416 priv->numbers_font = NULL;
417 priv->print_numbers = 1;
418 priv->margin_top = 0.0;
419 priv->margin_bottom = 0.0;
420 priv->margin_left = 0.0;
421 priv->margin_right = 0.0;
423 priv->print_header = FALSE;
424 priv->print_footer = FALSE;
425 priv->header_footer_font = NULL;
426 priv->header_format_left = NULL;
427 priv->header_format_center = NULL;
428 priv->header_format_right = NULL;
429 priv->header_separator = FALSE;
430 priv->footer_format_left = NULL;
431 priv->footer_format_center = NULL;
432 priv->footer_format_right = NULL;
433 priv->footer_separator = FALSE;
436 priv->printing = FALSE;
437 priv->print_ctxt = NULL;
438 priv->print_job = NULL;
440 priv->page_count = 0;
442 priv->first_line_number = 0;
443 priv->paragraphs = NULL;
444 priv->tag_styles = NULL;
446 /* some default, sane values */
447 priv->page_width = A4_WIDTH;
448 priv->page_height = A4_HEIGHT;
449 priv->doc_margin_top = CM (1);
450 priv->doc_margin_left = CM (1);
451 priv->doc_margin_right = CM (1);
452 priv->doc_margin_bottom = CM (1);
456 free_paragraphs (GSList *paras)
458 while (paras != NULL)
460 Paragraph *para = paras->data;
461 TextSegment *seg = para->segment;
464 TextSegment *next = seg->next;
470 paras = g_slist_delete_link (paras, paras);
475 gtk_source_print_job_finalize (GObject *object)
477 GtkSourcePrintJob *job;
478 GtkSourcePrintJobPrivate *priv;
480 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (object));
482 job = GTK_SOURCE_PRINT_JOB (object);
487 if (priv->config != NULL)
488 gnome_print_config_unref (priv->config);
489 if (priv->buffer != NULL)
490 g_object_unref (priv->buffer);
491 if (priv->font != NULL)
492 pango_font_description_free (priv->font);
493 if (priv->numbers_font != NULL)
494 pango_font_description_free (priv->numbers_font);
495 if (priv->header_footer_font != NULL)
496 pango_font_description_free (priv->header_footer_font);
497 g_free (priv->header_format_left);
498 g_free (priv->header_format_right);
499 g_free (priv->header_format_center);
500 g_free (priv->footer_format_left);
501 g_free (priv->footer_format_right);
502 g_free (priv->footer_format_center);
504 if (priv->print_ctxt != NULL)
505 g_object_unref (priv->print_ctxt);
506 if (priv->print_job != NULL)
507 g_object_unref (priv->print_job);
508 if (priv->pango_context != NULL)
509 g_object_unref (priv->pango_context);
510 if (priv->tab_array != NULL)
511 pango_tab_array_free (priv->tab_array);
513 if (priv->paragraphs != NULL)
514 free_paragraphs (priv->paragraphs);
515 if (priv->tag_styles != NULL)
516 g_hash_table_destroy (priv->tag_styles);
522 G_OBJECT_CLASS (parent_class)->finalize (object);
526 gtk_source_print_job_get_property (GObject *object,
531 GtkSourcePrintJob *job = GTK_SOURCE_PRINT_JOB (object);
536 g_value_set_object (value, job->priv->config);
540 g_value_set_object (value, job->priv->buffer);
543 case PROP_TABS_WIDTH:
544 g_value_set_uint (value, job->priv->tabs_width);
548 g_value_set_enum (value, job->priv->wrap_mode);
552 g_value_set_boolean (value, job->priv->highlight);
556 g_value_take_string (value, gtk_source_print_job_get_font (job));
560 g_value_set_boxed (value, gtk_source_print_job_get_font_desc (job));
563 case PROP_NUMBERS_FONT:
564 g_value_take_string (value, gtk_source_print_job_get_numbers_font (job));
567 case PROP_NUMBERS_FONT_DESC:
568 g_value_set_boxed (value, gtk_source_print_job_get_numbers_font_desc (job));
571 case PROP_PRINT_NUMBERS:
572 g_value_set_uint (value, job->priv->print_numbers);
575 case PROP_PRINT_HEADER:
576 g_value_set_boolean (value, job->priv->print_header);
579 case PROP_PRINT_FOOTER:
580 g_value_set_boolean (value, job->priv->print_footer);
583 case PROP_HEADER_FOOTER_FONT:
584 g_value_take_string (value,
585 gtk_source_print_job_get_header_footer_font (job));
588 case PROP_HEADER_FOOTER_FONT_DESC:
589 g_value_set_boxed (value,
590 gtk_source_print_job_get_header_footer_font_desc (job));
594 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
600 gtk_source_print_job_set_property (GObject *object,
605 GtkSourcePrintJob *job = GTK_SOURCE_PRINT_JOB (object);
610 gtk_source_print_job_set_config (job, g_value_get_object (value));
614 gtk_source_print_job_set_buffer (job, g_value_get_object (value));
617 case PROP_TABS_WIDTH:
618 gtk_source_print_job_set_tabs_width (job, g_value_get_uint (value));
622 gtk_source_print_job_set_wrap_mode (job, g_value_get_enum (value));
626 gtk_source_print_job_set_highlight (job, g_value_get_boolean (value));
630 gtk_source_print_job_set_font (job, g_value_get_string (value));
634 gtk_source_print_job_set_font_desc (job, g_value_get_boxed (value));
637 case PROP_NUMBERS_FONT:
638 gtk_source_print_job_set_numbers_font (job, g_value_get_string (value));
641 case PROP_NUMBERS_FONT_DESC:
642 gtk_source_print_job_set_numbers_font_desc (job, g_value_get_boxed (value));
645 case PROP_PRINT_NUMBERS:
646 gtk_source_print_job_set_print_numbers (job, g_value_get_uint (value));
649 case PROP_PRINT_HEADER:
650 gtk_source_print_job_set_print_header (job, g_value_get_boolean (value));
653 case PROP_PRINT_FOOTER:
654 gtk_source_print_job_set_print_footer (job, g_value_get_boolean (value));
657 case PROP_HEADER_FOOTER_FONT:
658 gtk_source_print_job_set_header_footer_font (job,
659 g_value_get_string (value));
662 case PROP_HEADER_FOOTER_FONT_DESC:
663 gtk_source_print_job_set_header_footer_font_desc (job,
664 g_value_get_boxed (value));
668 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
674 gtk_source_print_job_begin_page (GtkSourcePrintJob *job)
676 cm_return_if_fail (job->priv->printing);
678 if (job->priv->print_header && job->priv->header_height > 0)
682 x = job->priv->doc_margin_left + job->priv->margin_left;
683 y = job->priv->page_height - job->priv->doc_margin_top - job->priv->margin_top;
684 default_print_header (job, x, y);
687 if (job->priv->print_footer && job->priv->footer_height > 0)
691 x = job->priv->doc_margin_left + job->priv->margin_left;
692 y = job->priv->doc_margin_bottom +
693 job->priv->margin_bottom +
694 job->priv->footer_height;
695 default_print_footer (job, x, y);
699 /* ---- gnome-print / Pango convenience functions */
701 /* Gets the width of a layout in gnome-print coordinates */
703 get_layout_width (PangoLayout *layout)
707 pango_layout_get_size (layout, &layout_width, NULL);
708 return (gdouble) layout_width / PANGO_SCALE;
711 /* Gets the ascent/descent of a font in gnome-print coordinates */
713 get_font_ascent_descent (GtkSourcePrintJob *job,
714 PangoFontDescription *desc,
718 PangoFontMetrics *metrics;
720 metrics = pango_context_get_metrics (job->priv->pango_context,
722 job->priv->language);
725 *ascent = (gdouble) pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
727 *descent = (gdouble) pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
729 pango_font_metrics_unref (metrics);
732 /* Draws the first line in a layout; we use this for one-line layouts
733 * to get baseline alignment */
735 show_first_layout_line (GnomePrintContext *print_ctxt,
738 PangoLayoutLine *line;
740 line = pango_layout_get_lines (layout)->data;
741 gnome_print_pango_layout_line (print_ctxt, line);
745 get_line_number_layout (GtkSourcePrintJob *job,
751 num_str = g_strdup_printf ("%d", line_number);
752 layout = pango_layout_new (job->priv->pango_context);
753 pango_layout_set_font_description (layout, job->priv->numbers_font);
754 pango_layout_set_text (layout, num_str, -1);
760 /* ---- Configuration functions */
763 ensure_print_config (GtkSourcePrintJob *job)
765 if (job->priv->config == NULL)
766 job->priv->config = gnome_print_config_default ();
767 if (job->priv->font == NULL)
768 job->priv->font = pango_font_description_from_string (DEFAULT_FONT_NAME);
772 update_page_size_and_margins (GtkSourcePrintJob *job)
775 gdouble ascent, descent;
777 gnome_print_job_get_page_size_from_config (job->priv->config,
778 &job->priv->page_width,
779 &job->priv->page_height);
781 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_TOP,
782 &job->priv->doc_margin_top, NULL);
783 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM,
784 &job->priv->doc_margin_bottom, NULL);
785 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_LEFT,
786 &job->priv->doc_margin_left, NULL);
787 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT,
788 &job->priv->doc_margin_right, NULL);
790 /* set default fonts for numbers and header/footer */
791 if (job->priv->numbers_font == NULL)
792 job->priv->numbers_font = pango_font_description_copy (job->priv->font);
794 if (job->priv->header_footer_font == NULL)
795 job->priv->header_footer_font = pango_font_description_copy (job->priv->font);
797 /* calculate numbers width */
798 if (job->priv->print_numbers > 0)
800 layout = get_line_number_layout (job, job->priv->last_line_number);
801 job->priv->numbers_width = get_layout_width (layout) + NUMBERS_TEXT_SEPARATION;
802 g_object_unref (layout);
805 job->priv->numbers_width = 0.0;
807 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
809 /* calculate header/footer height */
810 if (job->priv->print_header &&
811 (job->priv->header_format_left != NULL ||
812 job->priv->header_format_center != NULL ||
813 job->priv->header_format_right != NULL))
814 job->priv->header_height = HEADER_FOOTER_SIZE * (ascent + descent);
816 job->priv->header_height = 0.0;
818 if (job->priv->print_footer &&
819 (job->priv->footer_format_left != NULL ||
820 job->priv->footer_format_center != NULL ||
821 job->priv->footer_format_right != NULL))
822 job->priv->footer_height = HEADER_FOOTER_SIZE * (ascent + descent);
824 job->priv->footer_height = 0.0;
826 /* verify that the user provided margins are not too excesive
827 * and that we still have room for the text */
828 job->priv->text_width = (job->priv->page_width -
829 job->priv->doc_margin_left - job->priv->doc_margin_right -
830 job->priv->margin_left - job->priv->margin_right -
831 job->priv->numbers_width);
833 job->priv->text_height = (job->priv->page_height -
834 job->priv->doc_margin_top - job->priv->doc_margin_bottom -
835 job->priv->margin_top - job->priv->margin_bottom -
836 job->priv->header_height - job->priv->footer_height);
838 /* FIXME: put some saner values than 5cm - Gustavo */
839 cm_return_val_if_fail (job->priv->text_width > CM(5.0), FALSE);
840 cm_return_val_if_fail (job->priv->text_height > CM(5.0), FALSE);
845 /* We want a uniform tab width for the entire job without regard to style
846 * See comments in gtksourceview.c:calculate_real_tab_width
849 calculate_real_tab_width (GtkSourcePrintJob *job, guint tab_size, gchar c)
858 tab_string = g_strnfill (tab_size, c);
859 layout = pango_layout_new (job->priv->pango_context);
860 pango_layout_set_text (layout, tab_string, -1);
863 pango_layout_get_size (layout, &tab_width, NULL);
864 g_object_unref (G_OBJECT (layout));
870 setup_pango_context (GtkSourcePrintJob *job)
872 PangoFontMap *font_map;
875 if (!job->priv->pango_context)
877 font_map = gnome_print_pango_get_default_font_map ();
878 job->priv->pango_context = gnome_print_pango_create_context (font_map);
881 pango_context_set_language (job->priv->pango_context, job->priv->language);
882 pango_context_set_font_description (job->priv->pango_context, job->priv->font);
884 if (job->priv->tab_array)
886 pango_tab_array_free (job->priv->tab_array);
887 job->priv->tab_array = NULL;
890 real_tab_width = calculate_real_tab_width (job, job->priv->tabs_width, ' ');
891 if (real_tab_width > 0)
893 job->priv->tab_array = pango_tab_array_new (1, FALSE);
894 pango_tab_array_set_tab (job->priv->tab_array, 0, PANGO_TAB_LEFT, real_tab_width);
900 /* ----- Helper functions */
903 font_description_to_gnome_font_name (PangoFontDescription *desc)
905 GnomeFontFace *font_face;
908 /* Will always return some font */
909 font_face = gnome_font_face_find_closest_from_pango_description (desc);
911 retval = g_strdup_printf("%s %f",
912 gnome_font_face_get_name (font_face),
913 (double) pango_font_description_get_size (desc) / PANGO_SCALE);
914 g_object_unref (font_face);
920 * The following routines are duplicated in gedit/gedit/gedit-prefs-manager.c
923 /* Do this ourselves since gnome_font_find_closest() doesn't call
924 * gnome_font_face_find_closest() (probably a gnome-print bug)
927 face_and_size_from_full_name (const guchar *name,
928 GnomeFontFace **face,
934 copy = g_strdup (name);
935 str_size = strrchr (copy, ' ');
940 *size = atof (str_size);
947 *face = gnome_font_face_find_closest (copy);
951 static PangoFontDescription *
952 font_description_from_gnome_font_name (const char *font_name)
955 PangoFontDescription *desc;
960 face_and_size_from_full_name (font_name, &face, &size);
962 /* Pango and GnomePrint have basically the same numeric weight values */
963 weight = (PangoWeight) gnome_font_face_get_weight_code (face);
964 style = gnome_font_face_is_italic (face) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL;
966 desc = pango_font_description_new ();
967 pango_font_description_set_family (desc, gnome_font_face_get_family_name (face));
968 pango_font_description_set_weight (desc, weight);
969 pango_font_description_set_style (desc, style);
970 pango_font_description_set_size (desc, size * PANGO_SCALE);
972 g_object_unref (face);
977 /* ---- TextStyle functions */
980 text_style_new (GtkSourcePrintJob *job, GtkTextTag *tag)
983 gboolean bg_set, fg_set;
985 cm_return_val_if_fail (tag != NULL && GTK_IS_TEXT_TAG (tag), NULL);
987 style = g_new0 (TextStyle, 1);
989 g_object_get (G_OBJECT (tag),
990 "background_set", &bg_set,
991 "foreground_set", &fg_set,
992 "font_desc", &style->font_desc,
993 "scale", &style->scale,
994 "underline", &style->underline,
995 "strikethrough", &style->strikethrough,
999 g_object_get (G_OBJECT (tag), "foreground_gdk", &style->foreground, NULL);
1002 g_object_get (G_OBJECT (tag), "background_gdk", &style->background, NULL);
1008 text_style_free (TextStyle *style)
1010 pango_font_description_free (style->font_desc);
1011 if (style->foreground)
1012 gdk_color_free (style->foreground);
1013 if (style->background)
1014 gdk_color_free (style->background);
1019 get_style (GtkSourcePrintJob *job, const GtkTextIter *iter)
1022 GtkTextTag *tag = NULL;
1023 TextStyle *style = NULL;
1025 if (job->priv->tag_styles == NULL)
1027 job->priv->tag_styles = g_hash_table_new_full (
1028 g_direct_hash, g_direct_equal,
1029 NULL, (GDestroyNotify) text_style_free);
1032 /* get the tags at iter */
1033 tags = gtk_text_iter_get_tags (iter);
1035 /* now find the GtkSourceTag (if any) which applies at iter */
1036 /* FIXME: this makes the assumption that the style at a given
1037 * iter is only determined by one GtkSourceTag (the one with
1038 * highest priority). This is true for now, but could change
1039 * in the future - Gustavo */
1043 if (GTK_IS_TEXT_TAG (t->data))
1045 t = g_slist_next (t);
1047 g_slist_free (tags);
1049 /* now we lookup the tag style in the cache */
1052 style = g_hash_table_lookup (job->priv->tag_styles, tag);
1055 /* create a style for the tag and cache it */
1056 style = text_style_new (job, tag);
1057 g_hash_table_insert (job->priv->tag_styles, tag, style);
1064 /* ----- Text fetching functions */
1067 get_text_simple (GtkSourcePrintJob *job,
1073 while (gtk_text_iter_compare (start, end) < 0)
1078 /* get a line of text */
1080 if (!gtk_text_iter_ends_line (&iter))
1081 gtk_text_iter_forward_to_line_end (&iter);
1083 if (gtk_text_iter_compare (&iter, end) > 0)
1087 seg = g_new0 (TextSegment, 1);
1088 seg->next = NULL; /* only one segment per line, since there's no style change */
1089 seg->style = NULL; /* use default style */
1090 /* FIXME: handle invisible text properly. This also
1091 * assumes the text has no embedded images and
1093 seg->text = gtk_text_iter_get_slice (start, &iter);
1095 para = g_new0 (Paragraph, 1);
1096 para->segment = seg;
1098 /* add the line of text to the job */
1099 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1101 gtk_text_iter_forward_line (&iter);
1103 /* advance to next line */
1106 job->priv->paragraphs = g_slist_reverse (job->priv->paragraphs);
1112 get_text_with_style (GtkSourcePrintJob *job,
1116 GtkTextIter limit, next_toggle;
1117 gboolean have_toggle;
1118 GdkPixbuf *image = NULL;
1120 /* make sure the region to print is highlighted */
1121 /*_gtk_source_buffer_highlight_region (job->priv->buffer, start, end, TRUE); */
1123 next_toggle = *start;
1124 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1126 /* FIXME: handle invisible text properly. This also assumes
1127 * the text has no embedded images and stuff */
1128 while (gtk_text_iter_compare (start, end) < 0)
1134 para = g_new0 (Paragraph, 1);
1136 /* get the style at the start of the line */
1137 style = get_style (job, start);
1139 /* get a line of text - limit points to the end of the line */
1141 if (!gtk_text_iter_ends_line (&limit))
1142 gtk_text_iter_forward_to_line_end (&limit);
1144 if (gtk_text_iter_compare (&limit, end) > 0)
1147 /* create the first segment for the line */
1148 para->segment = seg = g_new0 (TextSegment, 1);
1151 /* while the next tag toggle is within the line, we check to see
1152 * if the style has changed at each tag toggle position, and if so,
1153 * create new segments */
1154 while (have_toggle && gtk_text_iter_compare (&next_toggle, &limit) < 0)
1156 /* check style changes */
1157 style = get_style (job, &next_toggle);
1158 if (style != seg->style)
1160 TextSegment *new_seg;
1161 /* style has changed, thus we need to
1162 * create a new segment */
1163 /* close the current segment */
1164 seg->text = gtk_text_iter_get_slice (start, &next_toggle);
1165 if ((image = gtk_text_iter_get_pixbuf(start)) != NULL)
1168 *start = next_toggle;
1170 new_seg = g_new0 (TextSegment, 1);
1171 seg->next = new_seg;
1176 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1179 /* close the line */
1181 seg->text = gtk_text_iter_get_slice (start, &limit);
1182 if ((image = gtk_text_iter_get_pixbuf(start)) != NULL)
1185 /* add the line of text to the job */
1186 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1188 /* advance to next line */
1190 gtk_text_iter_forward_line (start);
1192 if (gtk_text_iter_compare (&next_toggle, start) < 0) {
1193 next_toggle = *start;
1194 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1197 job->priv->paragraphs = g_slist_reverse (job->priv->paragraphs);
1203 get_text_to_print (GtkSourcePrintJob *job,
1204 const GtkTextIter *start,
1205 const GtkTextIter *end)
1207 GtkTextIter _start, _end;
1210 cm_return_val_if_fail (start != NULL && end != NULL, FALSE);
1211 cm_return_val_if_fail (job->priv->buffer != NULL, FALSE);
1216 /* erase any previous data */
1217 if (job->priv->paragraphs != NULL)
1219 free_paragraphs (job->priv->paragraphs);
1220 job->priv->paragraphs = NULL;
1222 if (job->priv->tag_styles != NULL)
1224 g_hash_table_destroy (job->priv->tag_styles);
1225 job->priv->tag_styles = NULL;
1228 /* provide ordered iters */
1229 gtk_text_iter_order (&_start, &_end);
1231 /* save the first and last line numbers for future reference */
1232 job->priv->first_line_number = gtk_text_iter_get_line (&_start) + 1;
1233 job->priv->last_line_number = gtk_text_iter_get_line (&_end) + 1;
1235 if (!job->priv->highlight)
1236 retval = get_text_simple (job, &_start, &_end);
1238 retval = get_text_with_style (job, &_start, &_end);
1240 if (retval && job->priv->paragraphs == NULL)
1245 /* add an empty line to allow printing empty documents */
1246 seg = g_new0 (TextSegment, 1);
1248 seg->style = NULL; /* use default style */
1249 seg->text = g_strdup ("");
1251 para = g_new0 (Paragraph, 1);
1252 para->segment = seg;
1254 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1260 /* ----- Pagination functions */
1263 add_attribute_to_list (PangoAttribute *attr,
1264 PangoAttrList *list,
1268 attr->start_index = index;
1269 attr->end_index = index + len;
1270 pango_attr_list_insert (list, attr);
1274 create_layout_for_para (GtkSourcePrintJob *job,
1279 PangoLayout *layout;
1280 PangoAttrList *attrs;
1283 GdkPixbuf *image = NULL;
1284 text = g_string_new (NULL);
1285 attrs = pango_attr_list_new ();
1287 seg = para->segment;
1292 gsize seg_len = strlen (seg->text);
1293 g_string_append (text, seg->text);
1297 PangoAttribute *attr;
1299 attr = pango_attr_font_desc_new (seg->style->font_desc);
1300 add_attribute_to_list (attr, attrs, index, seg_len);
1302 if (seg->style->scale != PANGO_SCALE_MEDIUM)
1304 attr = pango_attr_scale_new (seg->style->scale);
1305 add_attribute_to_list (attr, attrs, index, seg_len);
1308 if (seg->style->foreground)
1310 attr = pango_attr_foreground_new (seg->style->foreground->red,
1311 seg->style->foreground->green,
1312 seg->style->foreground->blue);
1313 add_attribute_to_list (attr, attrs, index, seg_len);
1316 if (seg->style->background)
1318 attr = pango_attr_background_new (seg->style->background->red,
1319 seg->style->background->green,
1320 seg->style->background->blue);
1321 add_attribute_to_list (attr, attrs, index, seg_len);
1324 if (seg->style->strikethrough)
1326 attr = pango_attr_strikethrough_new (TRUE);
1327 add_attribute_to_list (attr, attrs, index, seg_len);
1330 if (seg->style->underline != PANGO_UNDERLINE_NONE)
1332 attr = pango_attr_underline_new (seg->style->underline);
1333 add_attribute_to_list (attr, attrs, index, seg_len);
1345 if (image != NULL) {
1350 layout = pango_layout_new (job->priv->pango_context);
1352 pango_layout_set_width (layout, job->priv->text_width * PANGO_SCALE);
1354 switch (job->priv->wrap_mode) {
1356 pango_layout_set_wrap (layout, PANGO_WRAP_CHAR);
1359 pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
1361 case GTK_WRAP_WORD_CHAR:
1362 pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
1366 * Ellipsize the paragraph when text wrapping is disabled.
1367 * Another possibility would be to set the width so the text
1368 * breaks into multiple lines, and paginate/render just the
1370 * See also Comment #23 by Owen on bug #143874.
1373 /* orph says to comment this out and commit it.
1374 PANGO_ELLIPSIZE_END is not available in pango
1375 1.4.1, at least, and he says this code is never
1377 /*pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);*/
1382 if (job->priv->tab_array)
1383 pango_layout_set_tabs (layout, job->priv->tab_array);
1385 pango_layout_set_text (layout, text->str, text->len);
1386 pango_layout_set_attributes (layout, attrs);
1389 /* FIXME: <horrible-hack>
1390 * For empty paragraphs, pango_layout_iter_get_baseline() returns 0,
1391 * so I check this condition and add a space character to force
1392 * the calculation of the baseline. I don't like that, but I
1393 * didn't find a better way to do it. Note that a paragraph is
1394 * considered empty either when it has no characters, or when
1396 * See comment #22 and #23 on bug #143874.
1398 if (job->priv->print_numbers > 0)
1400 PangoLayoutIter *iter;
1401 iter = pango_layout_get_iter (layout);
1402 if (pango_layout_iter_get_baseline (iter) == 0)
1404 g_string_append_c (text, ' ');
1405 pango_layout_set_text (layout, text->str, text->len);
1407 pango_layout_iter_free (iter);
1409 /* FIXME: </horrible-hack> */
1411 g_string_free (text, TRUE);
1412 pango_attr_list_unref (attrs);
1417 /* The break logic in this function needs to match that in print_paragraph */
1419 paginate_paragraph (GtkSourcePrintJob *job,
1422 PangoLayout *layout;
1423 PangoLayoutIter *iter;
1424 PangoRectangle logical_rect;
1429 gboolean is_image = FALSE;
1431 tmp = create_layout_for_para (job, para, &is_image);
1433 layout = (PangoLayout *)tmp;
1436 image = (GdkPixbuf *)tmp;
1440 if (image == NULL) {
1441 iter = pango_layout_get_iter (layout);
1448 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
1449 max = (gdouble) (logical_rect.y + logical_rect.height) / PANGO_SCALE;
1451 if (max - page_skip > job->priv->available_height)
1453 /* "create" a new page */
1454 job->priv->page_count++;
1455 job->priv->available_height = job->priv->text_height;
1456 page_skip = (gdouble) logical_rect.y / PANGO_SCALE;
1460 while (pango_layout_iter_next_line (iter));
1461 job->priv->available_height -= max - page_skip;
1462 pango_layout_iter_free (iter);
1463 g_object_unref (layout);
1465 gint max_height = job->priv->available_height;
1466 gint image_height = gdk_pixbuf_get_height(image);
1467 gint image_width = gdk_pixbuf_get_width(image);
1468 gint scaled_height = 0, scaled_width = 0;
1469 image_viewer_get_resized_size(image_width,
1471 job->priv->text_width,
1472 job->priv->text_height,
1473 &scaled_width, &scaled_height);
1474 if (scaled_height > max_height) {
1475 job->priv->page_count++;
1476 job->priv->available_height = job->priv->text_height - scaled_height;
1478 job->priv->available_height -= scaled_height;
1485 paginate_text (GtkSourcePrintJob *job)
1490 /* set these to zero so the first break_line creates a new page */
1491 job->priv->page_count = 0;
1492 job->priv->available_height = 0;
1493 line_number = job->priv->first_line_number;
1494 l = job->priv->paragraphs;
1497 Paragraph *para = l->data;
1499 para->line_number = line_number;
1500 paginate_paragraph (job, para);
1503 l = g_slist_next (l);
1506 /* FIXME: do we have any error condition which can force us to
1507 * return %FALSE? - Gustavo */
1511 /* ---- Printing functions */
1514 begin_page (GtkSourcePrintJob *job)
1516 gnome_print_beginpage (job->priv->print_ctxt, NULL);
1518 g_signal_emit (job, print_job_signals [BEGIN_PAGE], 0);
1522 end_page (GtkSourcePrintJob *job)
1524 gnome_print_showpage (job->priv->print_ctxt);
1528 print_line_number (GtkSourcePrintJob *job,
1533 PangoLayout *layout;
1535 layout = get_line_number_layout (job, line_number);
1537 x = x + job->priv->numbers_width - get_layout_width (layout) - NUMBERS_TEXT_SEPARATION;
1538 gnome_print_moveto (job->priv->print_ctxt, x, y);
1540 show_first_layout_line (job->priv->print_ctxt, layout);
1542 g_object_unref (layout);
1545 /* The break logic in this function needs to match that in paginate_paragraph
1547 * @start_line is the first line in the paragraph to print
1548 * @y is updated to the position after the portion of the paragraph we printed
1549 * @baseline_out is set to the baseline of the first line of the paragraph
1550 * if we printed it. (And not set otherwise)
1552 * Returns the first unprinted line in the paragraph (unprinted because it
1553 * flowed onto the next page) or -1 if the entire paragraph was printed.
1556 print_paragraph (GtkSourcePrintJob *job,
1561 gdouble *baseline_out,
1564 PangoLayout *layout;
1565 PangoLayoutIter *iter;
1566 PangoRectangle logical_rect;
1576 tmp = create_layout_for_para (job, para, &is_image);
1578 layout = (PangoLayout *)tmp;
1581 image = (GdkPixbuf *)tmp;
1586 iter = pango_layout_get_iter (layout);
1588 /* Skip over lines already printed on previous page(s) */
1589 for (current_line = 0; current_line < start_line; current_line++)
1590 pango_layout_iter_next_line (iter);
1597 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
1598 max = (gdouble) (logical_rect.y + logical_rect.height) / PANGO_SCALE;
1600 if (current_line == start_line)
1601 page_skip = (gdouble) logical_rect.y / PANGO_SCALE;
1603 if (max - page_skip > job->priv->available_height)
1605 result = current_line; /* Save position for next page */
1609 baseline = (gdouble) pango_layout_iter_get_baseline (iter) / PANGO_SCALE;
1610 baseline = *y + page_skip - baseline; /* Adjust to global coordinates */
1611 if (current_line == 0)
1612 *baseline_out = baseline;
1614 gnome_print_moveto (job->priv->print_ctxt,
1615 x + (gdouble) logical_rect.x / PANGO_SCALE,
1617 gnome_print_pango_layout_line (job->priv->print_ctxt,
1618 pango_layout_iter_get_line (iter));
1622 while (pango_layout_iter_next_line (iter));
1624 job->priv->available_height -= max - page_skip;
1625 *y -= max - page_skip;
1627 pango_layout_iter_free (iter);
1628 g_object_unref (layout);
1630 gint max_height = job->priv->available_height;
1631 gint image_height = gdk_pixbuf_get_height(image);
1632 gint image_width = gdk_pixbuf_get_width(image);
1633 gint scaled_height = 0, scaled_width = 0;
1634 GdkPixbuf *scaled_image = NULL;
1635 image_viewer_get_resized_size(image_width,
1637 job->priv->text_width,
1638 job->priv->text_height,
1639 &scaled_width, &scaled_height);
1641 if (scaled_height > max_height) {
1645 scaled_image = gdk_pixbuf_scale_simple
1646 (image, scaled_width, scaled_height,
1647 GDK_INTERP_BILINEAR);
1649 gnome_print_moveto(job->priv->print_ctxt,
1651 gnome_print_gsave(job->priv->print_ctxt);
1652 gnome_print_translate(job->priv->print_ctxt,
1653 x, *y - scaled_height);
1654 gnome_print_scale(job->priv->print_ctxt,
1658 if (gdk_pixbuf_get_has_alpha(image))
1659 gnome_print_rgbaimage (job->priv->print_ctxt,
1660 gdk_pixbuf_get_pixels (scaled_image),
1661 gdk_pixbuf_get_width (scaled_image),
1662 gdk_pixbuf_get_height (scaled_image),
1663 gdk_pixbuf_get_rowstride (scaled_image));
1665 gnome_print_rgbimage (job->priv->print_ctxt,
1666 gdk_pixbuf_get_pixels (scaled_image),
1667 gdk_pixbuf_get_width (scaled_image),
1668 gdk_pixbuf_get_height (scaled_image),
1669 gdk_pixbuf_get_rowstride (scaled_image));
1670 g_object_unref(scaled_image);
1671 gnome_print_grestore(job->priv->print_ctxt);
1673 job->priv->available_height -= scaled_height;
1674 *y -= scaled_height;
1683 print_page (GtkSourcePrintJob *job)
1688 gboolean force_fit = TRUE;
1694 job->priv->available_height = job->priv->text_height;
1696 y = job->priv->page_height -
1697 job->priv->doc_margin_top - job->priv->margin_top -
1698 job->priv->header_height;
1699 x = job->priv->doc_margin_left + job->priv->margin_left +
1700 job->priv->numbers_width;
1701 l = job->priv->current_paragraph;
1702 line = job->priv->current_paragraph_line;
1706 Paragraph *para = l->data;
1707 gdouble baseline = 0;
1708 gint last_line = line;
1710 line = print_paragraph (job, para, line, x, &y, &baseline, force_fit);
1712 if (last_line == 0 && line != 0)
1714 /* We printed the first line of a paragraph */
1715 if (job->priv->print_numbers > 0 &&
1716 ((para->line_number % job->priv->print_numbers) == 0))
1717 print_line_number (job,
1719 job->priv->doc_margin_left +
1720 job->priv->margin_left,
1723 job->priv->printed_lines++;
1727 break; /* Didn't all fit on this page */
1734 job->priv->current_paragraph = l;
1735 job->priv->current_paragraph_line = line;
1739 setup_for_print (GtkSourcePrintJob *job)
1741 job->priv->current_paragraph = job->priv->paragraphs;
1742 job->priv->page = 0;
1743 job->priv->printed_lines = 0;
1745 if (job->priv->print_job != NULL)
1746 g_object_unref (job->priv->print_job);
1747 if (job->priv->print_ctxt != NULL)
1748 g_object_unref (job->priv->print_ctxt);
1750 job->priv->print_job = gnome_print_job_new (job->priv->config);
1751 job->priv->print_ctxt = gnome_print_job_get_context (job->priv->print_job);
1753 gnome_print_pango_update_context (job->priv->pango_context, job->priv->print_ctxt);
1757 print_job (GtkSourcePrintJob *job)
1759 while (job->priv->current_paragraph != NULL)
1762 gnome_print_job_close (job->priv->print_job);
1766 idle_printing_handler (GtkSourcePrintJob *job)
1768 g_assert (job->priv->current_paragraph != NULL);
1772 if (job->priv->current_paragraph == NULL)
1774 gnome_print_job_close (job->priv->print_job);
1775 job->priv->printing = FALSE;
1776 job->priv->idle_printing_tag = 0;
1778 g_signal_emit (job, print_job_signals [FINISHED], 0);
1779 /* after this the print job object is possibly
1780 * destroyed (common use case) */
1788 /* Public API ------------------- */
1791 * gtk_source_print_job_new:
1792 * @config: an optional #GnomePrintConfig object.
1794 * Creates a new print job object, initially setting the print configuration.
1796 * Return value: the new print job object.
1799 gtk_source_print_job_new (GnomePrintConfig *config)
1801 GtkSourcePrintJob *job;
1803 cm_return_val_if_fail (config == NULL || GNOME_IS_PRINT_CONFIG (config), NULL);
1805 job = GTK_SOURCE_PRINT_JOB (g_object_new (GTK_TYPE_SOURCE_PRINT_JOB, NULL));
1807 gtk_source_print_job_set_config (job, config);
1813 * gtk_source_print_job_new_with_buffer:
1814 * @config: an optional #GnomePrintConfig.
1815 * @buffer: the #GtkTextBuffer to print (might be %NULL).
1817 * Creates a new print job to print @buffer.
1819 * Return value: a new print job object.
1822 gtk_source_print_job_new_with_buffer (GnomePrintConfig *config,
1823 GtkTextBuffer *buffer)
1825 GtkSourcePrintJob *job;
1827 cm_return_val_if_fail (config == NULL || GNOME_IS_PRINT_CONFIG (config), NULL);
1828 cm_return_val_if_fail (buffer == NULL || GTK_IS_TEXT_BUFFER (buffer), NULL);
1830 job = gtk_source_print_job_new (config);
1832 gtk_source_print_job_set_buffer (job, buffer);
1837 /* --- print job basic configuration */
1840 * gtk_source_print_job_set_config:
1841 * @job: a #GtkSourcePrintJob.
1842 * @config: a #GnomePrintConfig object to get printing configuration from.
1844 * Sets the print configuration for the job. If you don't set a
1845 * configuration object for the print job, when needed one will be
1846 * created with gnome_print_config_default().
1849 gtk_source_print_job_set_config (GtkSourcePrintJob *job,
1850 GnomePrintConfig *config)
1852 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1853 cm_return_if_fail (GNOME_IS_PRINT_CONFIG (config));
1854 cm_return_if_fail (!job->priv->printing);
1856 if (config == job->priv->config)
1859 if (job->priv->config != NULL)
1860 gnome_print_config_unref (job->priv->config);
1862 job->priv->config = config;
1863 gnome_print_config_ref (config);
1865 g_object_notify (G_OBJECT (job), "config");
1869 * gtk_source_print_job_get_config:
1870 * @job: a #GtkSourcePrintJob.
1872 * Gets the current #GnomePrintConfig the print job will use. If not
1873 * previously set, this will create a default configuration and return
1874 * it. The returned object reference is owned by the print job.
1876 * Return value: the #GnomePrintConfig for the print job.
1879 gtk_source_print_job_get_config (GtkSourcePrintJob *job)
1881 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
1883 ensure_print_config (job);
1885 return job->priv->config;
1889 * gtk_source_print_job_set_buffer:
1890 * @job: a #GtkSourcePrintJob.
1891 * @buffer: a #GtkTextBuffer.
1893 * Sets the #GtkTextBuffer the print job will print. You need to
1894 * specify a buffer to print, either by the use of this function or by
1895 * creating the print job with gtk_source_print_job_new_with_buffer().
1898 gtk_source_print_job_set_buffer (GtkSourcePrintJob *job,
1899 GtkTextBuffer *buffer)
1901 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1902 cm_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1903 cm_return_if_fail (!job->priv->printing);
1905 if (buffer == job->priv->buffer)
1908 if (job->priv->buffer != NULL)
1909 g_object_unref (job->priv->buffer);
1911 job->priv->buffer = buffer;
1912 g_object_ref (buffer);
1914 g_object_notify (G_OBJECT (job), "buffer");
1918 * gtk_source_print_job_get_buffer:
1919 * @job: a #GtkSourcePrintJob.
1921 * Gets the #GtkTextBuffer the print job would print. The returned
1922 * object reference (if non %NULL) is owned by the job object and
1923 * should not be unreferenced.
1925 * Return value: the #GtkTextBuffer to print.
1928 gtk_source_print_job_get_buffer (GtkSourcePrintJob *job)
1930 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
1932 return job->priv->buffer;
1935 /* --- print job layout and style configuration */
1938 * gtk_source_print_job_set_tabs_width:
1939 * @job: a #GtkSourcePrintJob.
1940 * @tabs_width: the number of equivalent spaces for a tabulation.
1942 * Sets the width (in equivalent spaces) of tabulations for the
1943 * printed text. The width in printing units will be calculated as
1944 * the width of a string containing @tabs_width spaces of the default
1945 * font. Tabulation stops are set for the full width of printed text.
1948 gtk_source_print_job_set_tabs_width (GtkSourcePrintJob *job,
1951 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1952 cm_return_if_fail (!job->priv->printing);
1954 if (tabs_width == job->priv->tabs_width)
1957 job->priv->tabs_width = tabs_width;
1959 g_object_notify (G_OBJECT (job), "tabs_width");
1963 * gtk_source_print_job_get_tabs_width:
1964 * @job: a #GtkSourcePrintJob.
1966 * Determines the configured width (in equivalent spaces) of
1967 * tabulations. The default value is 8.
1969 * Return value: the width (in equivalent spaces) of a tabulation.
1972 gtk_source_print_job_get_tabs_width (GtkSourcePrintJob *job)
1974 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
1976 return job->priv->tabs_width;
1980 * gtk_source_print_job_set_wrap_mode:
1981 * @job: a #GtkSourcePrintJob.
1982 * @wrap: the wrap mode.
1984 * Sets the wrap mode for lines of text larger than the printable
1985 * width. See #GtkWrapMode for a definition of the possible values.
1988 gtk_source_print_job_set_wrap_mode (GtkSourcePrintJob *job,
1991 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1992 cm_return_if_fail (!job->priv->printing);
1994 if (wrap == job->priv->wrap_mode)
1997 job->priv->wrap_mode = wrap;
1999 g_object_notify (G_OBJECT (job), "wrap_mode");
2003 * gtk_source_print_job_get_wrap_mode:
2004 * @job: a #GtkSourcePrintJob.
2006 * Determines the wrapping style for text lines wider than the
2007 * printable width. The default is no wrapping.
2009 * Return value: the current wrapping mode for the print job.
2012 gtk_source_print_job_get_wrap_mode (GtkSourcePrintJob *job)
2014 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), GTK_WRAP_NONE);
2016 return job->priv->wrap_mode;
2020 * gtk_source_print_job_set_highlight:
2021 * @job: a #GtkSourcePrintJob.
2022 * @highlight: %TRUE if the printed text should be highlighted.
2024 * Sets whether the printed text will be highlighted according to the
2025 * buffer rules. Both color and font style are applied.
2028 gtk_source_print_job_set_highlight (GtkSourcePrintJob *job,
2031 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2032 cm_return_if_fail (!job->priv->printing);
2034 highlight = (highlight != FALSE);
2036 if (highlight == job->priv->highlight)
2039 job->priv->highlight = highlight;
2041 g_object_notify (G_OBJECT (job), "highlight");
2045 * gtk_source_print_job_get_highlight:
2046 * @job: a #GtkSourcePrintJob.
2048 * Determines if the job is configured to print the text highlighted
2049 * with colors and font styles. Note that highlighting will happen
2050 * only if the buffer to print has highlighting activated.
2052 * Return value: %TRUE if the printed output will be highlighted.
2055 gtk_source_print_job_get_highlight (GtkSourcePrintJob *job)
2057 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2059 return job->priv->highlight;
2063 * gtk_source_print_job_set_font_desc:
2064 * @job: a #GtkSourcePrintJob.
2065 * @desc: the #PangoFontDescription for the default font
2067 * Sets the default font for the printed text.
2070 gtk_source_print_job_set_font_desc (GtkSourcePrintJob *job,
2071 PangoFontDescription *desc)
2073 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2074 cm_return_if_fail (desc != NULL);
2075 cm_return_if_fail (!job->priv->printing);
2077 desc = pango_font_description_copy (desc);
2078 if (job->priv->font != NULL)
2079 pango_font_description_free (job->priv->font);
2080 job->priv->font = desc;
2081 g_object_freeze_notify (G_OBJECT (job));
2082 g_object_notify (G_OBJECT (job), "font");
2083 g_object_notify (G_OBJECT (job), "font_desc");
2084 g_object_thaw_notify (G_OBJECT (job));
2088 * gtk_source_print_job_set_font:
2089 * @job: a #GtkSourcePrintJob.
2090 * @font_name: the name of the default font.
2092 * Sets the default font for the printed text. @font_name should be a
2093 * <emphasis>full font name</emphasis> GnomePrint can understand
2094 * (e.g. "Monospace Regular 10.0").
2096 * Note that @font_name is a #GnomeFont name not a Pango font
2097 * description string. This function is deprecated since #GnomeFont is
2098 * no longer used when implementing printing for GtkSourceView; you
2099 * should use gtk_source_print_job_set_font_desc() instead.
2102 gtk_source_print_job_set_font (GtkSourcePrintJob *job,
2103 const gchar *font_name)
2105 PangoFontDescription *desc;
2107 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2108 cm_return_if_fail (font_name != NULL);
2109 cm_return_if_fail (!job->priv->printing);
2111 desc = font_description_from_gnome_font_name (font_name);
2114 gtk_source_print_job_set_font_desc (job, desc);
2115 pango_font_description_free (desc);
2120 * gtk_source_print_job_get_font_desc:
2121 * @job: a #GtkSourcePrintJob.
2123 * Determines the default font to be used for the printed text. The
2124 * returned string is of the form "Fontfamily Style Size",
2125 * for example "Monospace Regular 10.0". The returned value
2126 * should be freed when no longer needed.
2128 * Return value: the current text font description. This value is
2129 * owned by the job and must not be modified or freed.
2131 PangoFontDescription *
2132 gtk_source_print_job_get_font_desc (GtkSourcePrintJob *job)
2134 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2136 ensure_print_config (job);
2138 return job->priv->font;
2142 * gtk_source_print_job_get_font:
2143 * @job: a #GtkSourcePrintJob.
2145 * Determines the default font to be used for the printed text. The
2146 * returned string is of the form "Fontfamily Style Size",
2147 * for example "Monospace Regular 10.0". The returned value
2148 * should be freed when no longer needed.
2150 * Note that the result is a #GnomeFont name not a Pango font
2151 * description string. This function is deprecated since #GnomeFont is
2152 * no longer used when implementing printing for GtkSourceView; you
2153 * should use gtk_source_print_job_get_font_desc() instead.
2155 * Return value: a newly allocated string with the name of the current
2159 gtk_source_print_job_get_font (GtkSourcePrintJob *job)
2161 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2163 ensure_print_config (job);
2165 return font_description_to_gnome_font_name (job->priv->font);
2169 * gtk_source_print_job_setup_from_view:
2170 * @job: a #GtkSourcePrintJob.
2171 * @view: a #GtkSourceView to get configuration from.
2173 * Convenience function to set several configuration options at once,
2174 * so that the printed output matches @view. The options set are
2175 * buffer (if not set already), tabs width, highlighting, wrap mode
2179 gtk_source_print_job_setup_from_view (GtkSourcePrintJob *job,
2182 GtkTextBuffer *buffer = NULL;
2183 PangoContext *pango_context;
2185 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2186 cm_return_if_fail (!job->priv->printing);
2188 buffer = gtk_text_view_get_buffer (view);
2190 if (job->priv->buffer == NULL && buffer != NULL)
2191 gtk_source_print_job_set_buffer (job, buffer);
2193 /* gtk_source_print_job_set_tabs_width (job, gtk_source_view_get_tabs_width (view)); */
2194 gtk_source_print_job_set_highlight (job, TRUE);
2195 gtk_source_print_job_set_wrap_mode (job, gtk_text_view_get_wrap_mode (view));
2197 pango_context = gtk_widget_get_pango_context (GTK_WIDGET (view));
2198 gtk_source_print_job_set_font_desc (job,
2199 pango_context_get_font_description (pango_context));
2203 * gtk_source_print_job_set_numbers_font_desc:
2204 * @job: a #GtkSourcePrintJob.
2205 * @desc: the #PangoFontDescription for the font for line numbers, or %NULL
2207 * Sets the font for printing line numbers on the left margin. If
2208 * NULL is supplied, the default font (i.e. the one being used for the
2209 * text) will be used instead.
2212 gtk_source_print_job_set_numbers_font_desc (GtkSourcePrintJob *job,
2213 PangoFontDescription *desc)
2215 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2216 cm_return_if_fail (!job->priv->printing);
2219 desc = pango_font_description_copy (desc);
2220 if (job->priv->numbers_font != NULL)
2221 pango_font_description_free (job->priv->numbers_font);
2222 job->priv->numbers_font = desc;
2223 g_object_freeze_notify (G_OBJECT (job));
2224 g_object_notify (G_OBJECT (job), "numbers_font");
2225 g_object_notify (G_OBJECT (job), "numbers_font_desc");
2226 g_object_thaw_notify (G_OBJECT (job));
2230 * gtk_source_print_job_set_numbers_font:
2231 * @job: a #GtkSourcePrintJob.
2232 * @font_name: the full name of the font for line numbers, or %NULL.
2234 * Sets the font for printing line numbers on the left margin. If
2235 * %NULL is supplied, the default font (i.e. the one being used for the
2236 * text) will be used instead.
2238 * Note that @font_name is a #GnomeFont name not a Pango font
2239 * description string. This function is deprecated since #GnomeFont is
2240 * no longer used when implementing printing for GtkSourceView; you
2241 * should use gtk_source_print_job_set_numbers_font_desc() instead.
2244 gtk_source_print_job_set_numbers_font (GtkSourcePrintJob *job,
2245 const gchar *font_name)
2247 PangoFontDescription *desc;
2249 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2250 cm_return_if_fail (!job->priv->printing);
2252 if (font_name != NULL)
2254 desc = font_description_from_gnome_font_name (font_name);
2257 gtk_source_print_job_set_numbers_font_desc (job, desc);
2258 pango_font_description_free (desc);
2262 gtk_source_print_job_set_numbers_font (job, NULL);
2266 * gtk_source_print_job_get_numbers_font_desc:
2267 * @job: a #GtkSourcePrintJob.
2269 * Determines the font to be used for the line numbers. This function
2270 * might return %NULL if a specific font for numbers has not been set.
2272 * Return value: the line numbers font description or %NULL. This value is
2273 * owned by the job and must not be modified or freed.
2275 PangoFontDescription *
2276 gtk_source_print_job_get_numbers_font_desc (GtkSourcePrintJob *job)
2278 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2280 return job->priv->numbers_font;
2284 * gtk_source_print_job_get_numbers_font:
2285 * @job: a #GtkSourcePrintJob.
2287 * Determines the font to be used for the line numbers. The returned
2288 * string is of the form "Fontfamily Style Size", for
2289 * example "Monospace Regular 10.0". The returned value
2290 * should be freed when no longer needed. This function might return
2291 * %NULL if a specific font for numbers has not been set.
2293 * Note that the result is a #GnomeFont name not a Pango font
2294 * description string. This function is deprecated since #GnomeFont is
2295 * no longer used when implementing printing for GtkSourceView; you
2296 * should use gtk_source_print_job_get_numbers_font_desc() instead.
2298 * Return value: a newly allocated string with the name of the current
2299 * line numbers font, or %NULL.
2302 gtk_source_print_job_get_numbers_font (GtkSourcePrintJob *job)
2304 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2306 if (job->priv->numbers_font != NULL)
2307 return font_description_to_gnome_font_name (job->priv->numbers_font);
2313 * gtk_source_print_job_set_print_numbers:
2314 * @job: a #GtkSourcePrintJob.
2315 * @interval: interval for printed line numbers.
2317 * Sets the interval for printed line numbers. If @interval is 0 no
2318 * numbers will be printed. If greater than 0, a number will be
2319 * printed every @interval lines (i.e. 1 will print all line numbers).
2322 gtk_source_print_job_set_print_numbers (GtkSourcePrintJob *job,
2325 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2326 cm_return_if_fail (!job->priv->printing);
2328 if (interval == job->priv->print_numbers)
2331 job->priv->print_numbers = interval;
2333 g_object_notify (G_OBJECT (job), "print_numbers");
2337 * gtk_source_print_job_get_print_numbers:
2338 * @job: a #GtkSourcePrintJob.
2340 * Determines the interval used for line number printing. If the
2341 * value is 0, no line numbers will be printed. The default value is
2342 * 1 (i.e. numbers printed in all lines).
2344 * Return value: the interval of printed line numbers.
2347 gtk_source_print_job_get_print_numbers (GtkSourcePrintJob *job)
2349 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2351 return job->priv->print_numbers;
2355 * gtk_source_print_job_set_text_margins:
2356 * @job: a #GtkSourcePrintJob.
2357 * @top: the top user margin.
2358 * @bottom: the bottom user margin.
2359 * @left: the left user margin.
2360 * @right: the right user margin.
2362 * Sets the four user margins for the print job. These margins are in
2363 * addition to the document margins provided in the #GnomePrintConfig
2364 * and will not be used for headers, footers or line numbers (those
2365 * are calculated separatedly). You can print in the space allocated
2366 * by these margins by connecting to the <link
2367 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link> signal. The
2368 * space is around the printed text, and inside the margins specified
2369 * in the #GnomePrintConfig.
2371 * The margin numbers are given in device units. If any of the given
2372 * values is less than 0, that particular margin is not altered by
2376 gtk_source_print_job_set_text_margins (GtkSourcePrintJob *job,
2382 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2383 cm_return_if_fail (!job->priv->printing);
2386 job->priv->margin_top = top;
2388 job->priv->margin_bottom = bottom;
2390 job->priv->margin_left = left;
2392 job->priv->margin_right = right;
2396 * gtk_source_print_job_get_text_margins:
2397 * @job: a #GtkSourcePrintJob.
2398 * @top: a pointer to a #gdouble to return the top margin.
2399 * @bottom: a pointer to a #gdouble to return the bottom margin.
2400 * @left: a pointer to a #gdouble to return the left margin.
2401 * @right: a pointer to a #gdouble to return the right margin.
2403 * Determines the user set margins for the job. This function
2404 * retrieves the values previously set by
2405 * gtk_source_print_job_set_text_margins(). The default for all four
2406 * margins is 0. Any of the pointers can be %NULL if you want to
2407 * ignore that value.
2410 gtk_source_print_job_get_text_margins (GtkSourcePrintJob *job,
2416 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2419 *top = job->priv->margin_top;
2421 *bottom = job->priv->margin_bottom;
2423 *left = job->priv->margin_left;
2425 *right = job->priv->margin_right;
2428 /* --- printing operations */
2431 gtk_source_print_job_prepare (GtkSourcePrintJob *job,
2432 const GtkTextIter *start,
2433 const GtkTextIter *end)
2435 PROFILE (GTimer *timer);
2437 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2438 cm_return_val_if_fail (!job->priv->printing, FALSE);
2439 cm_return_val_if_fail (job->priv->buffer != NULL, FALSE);
2440 cm_return_val_if_fail (start != NULL && end != NULL, FALSE);
2442 /* make sure we have a sane configuration to start printing */
2443 ensure_print_config (job);
2445 PROFILE (timer = g_timer_new ());
2447 /* get the text to print */
2448 if (!get_text_to_print (job, start, end))
2451 PROFILE (g_message ("get_text_to_print: %.2f", g_timer_elapsed (timer, NULL)));
2453 if (!setup_pango_context (job))
2457 if (!update_page_size_and_margins (job))
2460 /* split the document in pages */
2461 if (!paginate_text (job))
2465 g_message ("paginate_text: %.2f", g_timer_elapsed (timer, NULL));
2466 g_timer_destroy (timer);
2473 * gtk_source_print_job_print:
2474 * @job: a configured #GtkSourcePrintJob.
2476 * Produces a #GnomePrintJob with the printed document. The whole
2477 * contents of the configured #GtkTextBuffer are printed. The
2478 * returned job is already closed and ready to be previewed (using
2479 * gnome_print_job_preview_new()) or printed directly. The caller of
2480 * this function owns a reference to the returned object, so @job can
2481 * be destroyed and the output will still be valid, or the document
2482 * can be printed again with different settings.
2484 * Return value: a closed #GnomePrintJob with the printed document, or
2485 * %NULL if printing could not be completed.
2488 gtk_source_print_job_print (GtkSourcePrintJob *job)
2490 GtkTextIter start, end;
2492 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2493 cm_return_val_if_fail (!job->priv->printing, NULL);
2494 cm_return_val_if_fail (job->priv->buffer != NULL, NULL);
2496 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (job->priv->buffer), &start, &end);
2498 return gtk_source_print_job_print_range (job, &start, &end);
2502 * gtk_source_print_job_print_range:
2503 * @job: a configured #GtkSourcePrintJob.
2504 * @start: the start of the region of text to print.
2505 * @end: the end of the region of text to print.
2507 * Similar to gtk_source_print_job_print(), except you can specify a
2508 * range of text to print. The passed #GtkTextIter values might be
2511 * Return value: a closed #GnomePrintJob with the text from @start to
2512 * @end printed, or %NULL if @job could not print.
2515 gtk_source_print_job_print_range (GtkSourcePrintJob *job,
2516 const GtkTextIter *start,
2517 const GtkTextIter *end)
2519 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2520 cm_return_val_if_fail (!job->priv->printing, NULL);
2521 cm_return_val_if_fail (job->priv->buffer != NULL, NULL);
2522 cm_return_val_if_fail (start != NULL && end != NULL, NULL);
2523 cm_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
2524 GTK_TEXT_BUFFER (job->priv->buffer) &&
2525 gtk_text_iter_get_buffer (end) ==
2526 GTK_TEXT_BUFFER (job->priv->buffer), NULL);
2528 if (!gtk_source_print_job_prepare (job, start, end))
2531 /* real work starts here */
2532 setup_for_print (job);
2534 job->priv->printing = TRUE;
2536 job->priv->printing = FALSE;
2538 g_object_ref (job->priv->print_job);
2539 return job->priv->print_job;
2542 /* --- asynchronous printing */
2545 * gtk_source_print_job_print_range_async:
2546 * @job: a configured #GtkSourcePrintJob.
2547 * @start: the start of the region of text to print.
2548 * @end: the end of the region of text to print.
2550 * Starts to print @job asynchronously. This function will ready the
2551 * @job for printing and install an idle handler that will render one
2554 * This function will not return immediatly, as only page rendering is
2555 * done asynchronously. Text retrieval and paginating happens within
2556 * this function. Also, if highlighting is enabled, the whole buffer
2557 * needs to be highlighted first.
2559 * To get notification when the job has finished, you must connect to
2561 * linkend="GtkSourcePrintJob-finished">"finished"</link>
2562 * signal. After this signal is emitted you can retrieve the
2563 * resulting #GnomePrintJob with gtk_source_print_job_get_print_job().
2564 * You may cancel the job with gtk_source_print_job_cancel().
2566 * Return value: %TRUE if the print started.
2569 gtk_source_print_job_print_range_async (GtkSourcePrintJob *job,
2570 const GtkTextIter *start,
2571 const GtkTextIter *end)
2573 GSource *idle_source;
2575 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2576 cm_return_val_if_fail (!job->priv->printing, FALSE);
2577 cm_return_val_if_fail (job->priv->buffer != NULL, FALSE);
2578 cm_return_val_if_fail (start != NULL && end != NULL, FALSE);
2579 cm_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
2580 GTK_TEXT_BUFFER (job->priv->buffer) &&
2581 gtk_text_iter_get_buffer (end) ==
2582 GTK_TEXT_BUFFER (job->priv->buffer), FALSE);
2584 if (!gtk_source_print_job_prepare (job, start, end))
2587 /* real work starts here */
2588 setup_for_print (job);
2589 if (job->priv->current_paragraph == NULL)
2592 /* setup the idle handler to print each page at a time */
2593 idle_source = g_idle_source_new ();
2594 g_source_set_priority (idle_source, GTK_SOURCE_PRINT_JOB_PRIORITY);
2595 g_source_set_closure (idle_source,
2596 g_cclosure_new_object ((GCallback) idle_printing_handler,
2598 job->priv->idle_printing_tag = g_source_attach (idle_source, NULL);
2599 g_source_unref (idle_source);
2601 job->priv->printing = TRUE;
2607 * gtk_source_print_job_cancel:
2608 * @job: a #GtkSourcePrintJob.
2610 * Cancels an asynchronous printing operation. This will remove any
2611 * pending print idle handler and unref the current #GnomePrintJob.
2613 * Note that if you got a reference to the job's #GnomePrintJob (using
2614 * gtk_source_print_job_get_print_job()) it will not be destroyed
2615 * (since you hold a reference to it), but it will not be closed
2616 * either. If you wish to show or print the partially printed
2617 * document you need to close it yourself.
2619 * This function has no effect when called from a non-asynchronous
2623 gtk_source_print_job_cancel (GtkSourcePrintJob *job)
2625 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2626 cm_return_if_fail (job->priv->printing);
2628 if (job->priv->idle_printing_tag > 0)
2630 g_source_remove (job->priv->idle_printing_tag);
2631 job->priv->current_paragraph = NULL;
2632 job->priv->idle_printing_tag = 0;
2633 job->priv->printing = FALSE;
2634 g_object_unref (job->priv->print_job);
2635 g_object_unref (job->priv->print_ctxt);
2636 job->priv->print_job = NULL;
2637 job->priv->print_ctxt = NULL;
2642 * gtk_source_print_job_get_print_job:
2643 * @job: a #GtkSourcePrintJob.
2645 * Gets a reference to the #GnomePrintJob which the @job is printing
2646 * or has recently finished printing. You need to unref the returned
2649 * You may call this function in the middle of an asynchronous
2650 * printing operation, but the returned #GnomePrintJob will not be
2651 * closed until the last page is printed and the <link
2652 * linkend="GtkSourcePrintJob-finished">"finished"</link>
2653 * signal is emitted.
2655 * Return value: a new reference to the @job's #GnomePrintJob, or
2659 gtk_source_print_job_get_print_job (GtkSourcePrintJob *job)
2661 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2663 if (job->priv->print_job)
2664 g_object_ref (job->priv->print_job);
2666 return job->priv->print_job;
2669 /* --- information for asynchronous ops and headers and footers callback */
2672 * gtk_source_print_job_get_page:
2673 * @job: a #GtkSourcePrintJob.
2675 * Determines the currently printing page number. This function is
2676 * only valid while printing (either synchronously or asynchronously).
2678 * Return value: the current page number.
2681 gtk_source_print_job_get_page (GtkSourcePrintJob *job)
2683 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2684 cm_return_val_if_fail (job->priv->printing, 0);
2686 return job->priv->page;
2690 * gtk_source_print_job_get_page_count:
2691 * @job: a #GtkSourcePrintJob.
2693 * Determines the total number of pages the job will print. The
2694 * returned value is only meaninful after pagination has finished. In
2695 * practice, for synchronous printing this means when <link
2696 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link>
2697 * is emitted, or after gtk_source_print_job_print_range_async() has
2700 * Return value: the number of pages of the printed job.
2703 gtk_source_print_job_get_page_count (GtkSourcePrintJob *job)
2705 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2707 return job->priv->page_count;
2711 * gtk_source_print_job_get_print_context:
2712 * @job: a printing #GtkSourcePrintJob.
2714 * Determines the #GnomePrintContext of the current job. This
2715 * function is only valid while printing. Normally you would use this
2716 * function to print in the margins set by
2717 * gtk_source_print_job_set_margins() in a handler for the <link
2718 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link>
2721 * Return value: the current #GnomePrintContext. The returned object
2725 gtk_source_print_job_get_print_context (GtkSourcePrintJob *job)
2727 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2728 cm_return_val_if_fail (job->priv->printing, NULL);
2730 return job->priv->print_ctxt;
2733 /* ---- Header and footer (default implementation) */
2735 /* Most of this code taken from GLib's g_date_strftime() in gdate.c
2736 * GLIB - Library of useful routines for C programming
2737 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald */
2740 strdup_strftime (const gchar *format, const struct tm *tm)
2742 gsize locale_format_len = 0;
2743 gchar *locale_format;
2749 GError *error = NULL;
2751 cm_return_val_if_fail (format != NULL, NULL);
2752 cm_return_val_if_fail (tm != NULL, NULL);
2754 locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);
2758 g_warning (G_STRLOC "Error converting format to locale encoding: %s",
2760 g_error_free (error);
2765 tmpbufsize = MAX (128, locale_format_len * 2);
2768 tmpbuf = g_malloc (tmpbufsize);
2770 /* Set the first byte to something other than '\0', to be able to
2771 * recognize whether strftime actually failed or just returned "".
2774 tmplen = strftime (tmpbuf, tmpbufsize, locale_format, tm);
2776 if (tmplen == 0 && tmpbuf[0] != '\0')
2781 if (tmpbufsize > 65536)
2783 g_warning (G_STRLOC "Maximum buffer size for strdup_strftime "
2784 "exceeded: giving up");
2785 g_free (locale_format);
2792 g_free (locale_format);
2794 convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);
2799 g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s",
2801 g_error_free (error);
2810 evaluate_format_string (GtkSourcePrintJob *job, const gchar *format)
2813 gchar *eval_str, *retval;
2814 const struct tm *tm;
2821 tm = localtime_r(&now, <);
2823 /* analyze format string and replace the codes we know */
2824 eval = g_string_new_len (NULL, strlen (format));
2825 ch = g_utf8_get_char (format);
2830 format = g_utf8_next_char (format);
2831 ch = g_utf8_get_char (format);
2833 g_string_append_printf (eval, "%d", job->priv->page);
2835 g_string_append_printf (eval, "%d", job->priv->page_count);
2838 g_string_append_c (eval, '%');
2839 g_string_append_unichar (eval, ch);
2843 g_string_append_unichar (eval, ch);
2845 format = g_utf8_next_char (format);
2846 ch = g_utf8_get_char (format);
2849 eval_str = g_string_free (eval, FALSE);
2850 retval = strdup_strftime (eval_str, tm);
2857 print_header_footer_string (GtkSourcePrintJob *job,
2858 const gchar *format,
2863 PangoLayout *layout;
2868 width = job->priv->text_width + job->priv->numbers_width;
2870 text = evaluate_format_string (job, format);
2873 layout = pango_layout_new (job->priv->pango_context);
2874 pango_layout_set_font_description (layout, job->priv->header_footer_font);
2875 pango_layout_set_text (layout, text, -1);
2877 xx = x + x_align * (width - get_layout_width (layout));
2878 gnome_print_moveto (job->priv->print_ctxt, xx, y);
2879 show_first_layout_line (job->priv->print_ctxt, layout);
2882 g_object_unref (layout);
2887 default_print_header (GtkSourcePrintJob *job,
2893 gdouble ascent, descent;
2895 width = job->priv->text_width + job->priv->numbers_width;
2897 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
2902 if (job->priv->header_format_left != NULL)
2903 print_header_footer_string (job, job->priv->header_format_left, 0.0, x, yy);
2906 if (job->priv->header_format_right != NULL)
2907 print_header_footer_string (job, job->priv->header_format_right, 1.0, x, yy);
2910 if (job->priv->header_format_center != NULL)
2911 print_header_footer_string (job, job->priv->header_format_center, 0.5, x, yy);
2914 if (job->priv->header_separator)
2916 yy = y - (SEPARATOR_SPACING * (ascent + descent));
2917 gnome_print_setlinewidth (job->priv->print_ctxt, SEPARATOR_LINE_WIDTH);
2918 gnome_print_moveto (job->priv->print_ctxt, x, yy);
2919 gnome_print_lineto (job->priv->print_ctxt, x + width, yy);
2920 gnome_print_stroke (job->priv->print_ctxt);
2925 default_print_footer (GtkSourcePrintJob *job,
2931 gdouble ascent, descent;
2933 width = job->priv->text_width + job->priv->numbers_width;
2935 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
2937 yy = y - job->priv->footer_height + descent;
2940 if (job->priv->footer_format_left != NULL)
2941 print_header_footer_string (job, job->priv->footer_format_left, 0.0, x, yy);
2944 if (job->priv->footer_format_right != NULL)
2945 print_header_footer_string (job, job->priv->footer_format_right, 1.0, x, yy);
2948 if (job->priv->footer_format_center != NULL)
2949 print_header_footer_string (job, job->priv->footer_format_center, 0.5, x, yy);
2952 if (job->priv->footer_separator)
2954 yy = y - job->priv->footer_height +
2955 (SEPARATOR_SPACING * (ascent + descent));
2956 gnome_print_setlinewidth (job->priv->print_ctxt, SEPARATOR_LINE_WIDTH);
2957 gnome_print_moveto (job->priv->print_ctxt, x, yy);
2958 gnome_print_lineto (job->priv->print_ctxt, x + width, yy);
2959 gnome_print_stroke (job->priv->print_ctxt);
2964 * gtk_source_print_job_set_print_header:
2965 * @job: a #GtkSourcePrintJob.
2966 * @setting: %TRUE if you want the header to be printed.
2968 * Sets whether you want to print a header in each page. The default
2969 * header consists of three pieces of text and an optional line
2970 * separator, configurable with
2971 * gtk_source_print_job_set_header_format().
2973 * Note that by default the header format is unspecified, and if it's
2974 * empty it will not be printed, regardless of this setting.
2977 gtk_source_print_job_set_print_header (GtkSourcePrintJob *job,
2980 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2981 cm_return_if_fail (!job->priv->printing);
2983 setting = (setting != FALSE);
2985 if (setting == job->priv->print_header)
2988 job->priv->print_header = setting;
2990 g_object_notify (G_OBJECT (job), "print_header");
2994 * gtk_source_print_job_get_print_header:
2995 * @job: a #GtkSourcePrintJob.
2997 * Determines if a header is set to be printed for each page. A
2998 * header will be printed if this function returns %TRUE
2999 * <emphasis>and</emphasis> some format strings have been specified
3000 * with gtk_source_print_job_set_header_format().
3002 * Return value: %TRUE if the header is set to be printed.
3005 gtk_source_print_job_get_print_header (GtkSourcePrintJob *job)
3007 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
3009 return job->priv->print_header;
3013 * gtk_source_print_job_set_print_footer:
3014 * @job: a #GtkSourcePrintJob.
3015 * @setting: %TRUE if you want the footer to be printed.
3017 * Sets whether you want to print a footer in each page. The default
3018 * footer consists of three pieces of text and an optional line
3019 * separator, configurable with
3020 * gtk_source_print_job_set_footer_format().
3022 * Note that by default the footer format is unspecified, and if it's
3023 * empty it will not be printed, regardless of this setting.
3026 gtk_source_print_job_set_print_footer (GtkSourcePrintJob *job,
3029 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3030 cm_return_if_fail (!job->priv->printing);
3032 setting = (setting != FALSE);
3034 if (setting == job->priv->print_footer)
3037 job->priv->print_footer = setting;
3039 g_object_notify (G_OBJECT (job), "print_footer");
3043 * gtk_source_print_job_get_print_footer:
3044 * @job: a #GtkSourcePrintJob.
3046 * Determines if a footer is set to be printed for each page. A
3047 * footer will be printed if this function returns %TRUE
3048 * <emphasis>and</emphasis> some format strings have been specified
3049 * with gtk_source_print_job_set_footer_format().
3051 * Return value: %TRUE if the footer is set to be printed.
3054 gtk_source_print_job_get_print_footer (GtkSourcePrintJob *job)
3056 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
3058 return job->priv->print_footer;
3062 * gtk_source_print_job_set_header_footer_font_desc:
3063 * @job: a #GtkSourcePrintJob.
3064 * @desc: the #PangoFontDescription for the font to be used in headers and footers, or %NULL.
3066 * Sets the font for printing headers and footers. If %NULL is
3067 * supplied, the default font (i.e. the one being used for the text)
3068 * will be used instead.
3071 gtk_source_print_job_set_header_footer_font_desc (GtkSourcePrintJob *job,
3072 PangoFontDescription *desc)
3074 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3075 cm_return_if_fail (!job->priv->printing);
3078 desc = pango_font_description_copy (desc);
3079 if (job->priv->header_footer_font != NULL)
3080 pango_font_description_free (job->priv->header_footer_font);
3081 job->priv->header_footer_font = desc;
3082 g_object_freeze_notify (G_OBJECT (job));
3083 g_object_notify (G_OBJECT (job), "header_footer_font");
3084 g_object_notify (G_OBJECT (job), "header_footer_font_desc");
3085 g_object_thaw_notify (G_OBJECT (job));
3089 * gtk_source_print_job_set_header_footer_font:
3090 * @job: a #GtkSourcePrintJob.
3091 * @font_name: the full name of the font to be used in headers and footers, or %NULL.
3093 * Sets the font for printing headers and footers. If %NULL is
3094 * supplied, the default font (i.e. the one being used for the text)
3095 * will be used instead.
3097 * Note that @font_name is a #GnomeFont name not a Pango font
3098 * description string. This function is deprecated since #GnomeFont is
3099 * no longer used when implementing printing for GtkSourceView; you
3100 * should use gtk_source_print_job_set_header_footer_font_desc() instead.
3103 gtk_source_print_job_set_header_footer_font (GtkSourcePrintJob *job,
3104 const gchar *font_name)
3106 PangoFontDescription *desc;
3108 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3109 cm_return_if_fail (!job->priv->printing);
3111 if (font_name != NULL)
3113 desc = font_description_from_gnome_font_name (font_name);
3116 gtk_source_print_job_set_header_footer_font_desc (job, desc);
3117 pango_font_description_free (desc);
3121 gtk_source_print_job_set_header_footer_font_desc (job, NULL);
3125 * gtk_source_print_job_get_header_footer_font_desc:
3126 * @job: a #GtkSourcePrintJob.
3128 * Determines the font to be used for the header and footer. This function
3129 * might return %NULL if a specific font has not been set.
3131 * Return value: the header and footer font description or %NULL. This value is
3132 * owned by the job and must not be modified or freed.
3134 PangoFontDescription *
3135 gtk_source_print_job_get_header_footer_font_desc (GtkSourcePrintJob *job)
3137 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
3139 return job->priv->header_footer_font;
3143 * gtk_source_print_job_get_header_footer_font:
3144 * @job: a #GtkSourcePrintJob.
3146 * Determines the font to be used for the header and footer. The
3147 * returned string is of the form "Fontfamily Style Size",
3148 * for example "Monospace Regular 10.0". The returned value
3149 * should be freed when no longer needed. This function might return
3150 * %NULL if a specific font has not been set.
3152 * Note that the result is a #GnomeFont name not a Pango font
3153 * description string. This function is deprecated since #GnomeFont is
3154 * no longer used when implementing printing for GtkSourceView; you
3155 * should use gtk_source_print_job_get_header_footer_font_desc() instead.
3157 * Return value: a newly allocated string with the name of the current
3158 * header and footer font, or %NULL.
3161 gtk_source_print_job_get_header_footer_font (GtkSourcePrintJob *job)
3163 cm_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
3165 if (job->priv->header_footer_font != NULL)
3166 return font_description_to_gnome_font_name (job->priv->header_footer_font);
3172 * gtk_source_print_job_set_header_format:
3173 * @job: a #GtkSourcePrintJob.
3174 * @left: a format string to print on the left of the header.
3175 * @center: a format string to print on the center of the header.
3176 * @right: a format string to print on the right of the header.
3177 * @separator: %TRUE if you want a separator line to be printed.
3179 * Sets strftime like header format strings, to be printed on the
3180 * left, center and right of the top of each page. The strings may
3181 * include strftime(3) codes which will be expanded at print time.
3182 * All strftime() codes are accepted, with the addition of %N for the
3183 * page number and %Q for the page count.
3185 * @separator specifies if a solid line should be drawn to separate
3186 * the header from the document text.
3188 * If %NULL is given for any of the three arguments, that particular
3189 * string will not be printed. For the header to be printed, in
3190 * addition to specifying format strings, you need to enable header
3191 * printing with gtk_source_print_job_set_print_header().
3194 gtk_source_print_job_set_header_format (GtkSourcePrintJob *job,
3196 const gchar *center,
3200 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3201 cm_return_if_fail (!job->priv->printing);
3203 /* FIXME: validate given strings? */
3204 g_free (job->priv->header_format_left);
3205 g_free (job->priv->header_format_center);
3206 g_free (job->priv->header_format_right);
3207 job->priv->header_format_left = g_strdup (left);
3208 job->priv->header_format_center = g_strdup (center);
3209 job->priv->header_format_right = g_strdup (right);
3210 job->priv->header_separator = separator;
3214 * gtk_source_print_job_set_footer_format:
3215 * @job: a #GtkSourcePrintJob.
3216 * @left: a format string to print on the left of the footer.
3217 * @center: a format string to print on the center of the footer.
3218 * @right: a format string to print on the right of the footer.
3219 * @separator: %TRUE if you want a separator line to be printed.
3221 * Like gtk_source_print_job_set_header_format(), but for the footer.
3224 gtk_source_print_job_set_footer_format (GtkSourcePrintJob *job,
3226 const gchar *center,
3230 cm_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3231 cm_return_if_fail (!job->priv->printing);
3233 /* FIXME: validate given strings? */
3234 g_free (job->priv->footer_format_left);
3235 g_free (job->priv->footer_format_center);
3236 g_free (job->priv->footer_format_right);
3237 job->priv->footer_format_left = g_strdup (left);
3238 job->priv->footer_format_center = g_strdup (center);
3239 job->priv->footer_format_right = g_strdup (right);
3240 job->priv->footer_separator = separator;