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"
40 #include <glib/gi18n.h>
41 #include <gtk/gtkmain.h>
42 #include <gtk/gtktextview.h>
43 #include <libgnomeprint/gnome-print-pango.h>
58 #define DEFAULT_FONT_NAME "Monospace 10"
59 #define DEFAULT_COLOR 0x000000ff
61 #define CM(v) ((v) * 72.0 / 2.54)
62 #define A4_WIDTH (210.0 * 72 / 25.4)
63 #define A4_HEIGHT (297.0 * 72 / 25.4)
65 #define NUMBERS_TEXT_SEPARATION CM(0.5)
67 #define HEADER_FOOTER_SIZE 2.5
68 #define SEPARATOR_SPACING 1.5
69 #define SEPARATOR_LINE_WIDTH 1.0
72 typedef struct _TextSegment TextSegment;
73 typedef struct _Paragraph Paragraph;
74 typedef struct _TextStyle TextStyle;
76 /* a piece of text (within a paragraph) of the same style */
84 /* a printable line */
91 /* the style of a TextSegment */
94 PangoFontDescription *font_desc;
98 gboolean strikethrough;
99 PangoUnderline underline;
103 struct _GtkSourcePrintJobPrivate
105 /* General job configuration */
106 GnomePrintConfig *config;
107 GtkTextBuffer *buffer;
109 GtkWrapMode wrap_mode;
111 PangoLanguage *language;
112 PangoFontDescription *font;
113 PangoFontDescription *numbers_font;
116 gdouble margin_bottom;
118 gdouble margin_right;
120 /* Default header and footer configuration */
121 gboolean print_header;
122 gboolean print_footer;
123 PangoFontDescription *header_footer_font;
124 gchar *header_format_left;
125 gchar *header_format_center;
126 gchar *header_format_right;
127 gboolean header_separator;
128 gchar *footer_format_left;
129 gchar *footer_format_center;
130 gchar *footer_format_right;
131 gboolean footer_separator;
134 guint first_line_number;
135 guint last_line_number;
140 guint idle_printing_tag;
141 GnomePrintContext *print_ctxt;
142 GnomePrintJob *print_job;
143 PangoContext *pango_context;
144 PangoTabArray *tab_array;
147 gdouble available_height;
148 GSList *current_paragraph;
149 gint current_paragraph_line;
152 /* Cached information - all this information is obtained from
153 * other fields in the configuration */
154 GHashTable *tag_styles;
159 gdouble doc_margin_top;
160 gdouble doc_margin_left;
161 gdouble doc_margin_right;
162 gdouble doc_margin_bottom;
164 gdouble header_height;
165 gdouble footer_height;
166 gdouble numbers_width;
168 /* printable (for the document itself) size */
185 PROP_NUMBERS_FONT_DESC,
189 PROP_HEADER_FOOTER_FONT,
190 PROP_HEADER_FOOTER_FONT_DESC
200 static GObjectClass *parent_class = NULL;
201 static guint print_job_signals [LAST_SIGNAL] = { 0 };
203 static void gtk_source_print_job_class_init (GtkSourcePrintJobClass *klass);
204 static void gtk_source_print_job_instance_init (GtkSourcePrintJob *job);
205 static void gtk_source_print_job_finalize (GObject *object);
206 static void gtk_source_print_job_get_property (GObject *object,
210 static void gtk_source_print_job_set_property (GObject *object,
214 static void gtk_source_print_job_begin_page (GtkSourcePrintJob *job);
216 static void default_print_header (GtkSourcePrintJob *job,
219 static void default_print_footer (GtkSourcePrintJob *job,
225 gtk_source_print_job_get_type (void)
227 static GType our_type = 0;
231 static const GTypeInfo our_info = {
232 sizeof (GtkSourcePrintJobClass),
233 NULL, /* base_init */
234 NULL, /* base_finalize */
235 (GClassInitFunc) gtk_source_print_job_class_init,
236 NULL, /* class_finalize */
237 NULL, /* class_data */
238 sizeof (GtkSourcePrintJob),
240 (GInstanceInitFunc) gtk_source_print_job_instance_init
243 our_type = g_type_register_static (G_TYPE_OBJECT,
253 gtk_source_print_job_class_init (GtkSourcePrintJobClass *klass)
255 GObjectClass *object_class;
257 object_class = G_OBJECT_CLASS (klass);
258 parent_class = g_type_class_peek_parent (klass);
260 object_class->finalize = gtk_source_print_job_finalize;
261 object_class->get_property = gtk_source_print_job_get_property;
262 object_class->set_property = gtk_source_print_job_set_property;
264 klass->begin_page = gtk_source_print_job_begin_page;
265 klass->finished = NULL;
267 g_object_class_install_property (object_class,
269 g_param_spec_object ("config",
271 _("Configuration options for "
273 GNOME_TYPE_PRINT_CONFIG,
275 g_object_class_install_property (object_class,
277 g_param_spec_object ("buffer",
279 _("GtkTextBuffer object to print"),
280 GTK_TYPE_TEXT_BUFFER,
282 g_object_class_install_property (object_class,
284 g_param_spec_uint ("tabs_width",
286 _("Width in equivalent space "
287 "characters of tabs"),
290 g_object_class_install_property (object_class,
292 g_param_spec_enum ("wrap_mode",
294 _("Word wrapping mode"),
298 g_object_class_install_property (object_class,
300 g_param_spec_boolean ("highlight",
302 _("Whether to print the "
303 "document with highlighted "
307 g_object_class_install_property (object_class,
309 g_param_spec_string ("font",
311 _("GnomeFont name to use for the "
312 "document text (deprecated)"),
315 g_object_class_install_property (object_class,
317 g_param_spec_boxed ("font_desc",
318 _("Font Description"),
319 _("Font to use for the document text "
320 "(e.g. \"Monospace 10\")"),
321 PANGO_TYPE_FONT_DESCRIPTION,
323 g_object_class_install_property (object_class,
325 g_param_spec_string ("numbers_font",
327 _("GnomeFont name to use for the "
328 "line numbers (deprecated)"),
331 g_object_class_install_property (object_class,
332 PROP_NUMBERS_FONT_DESC,
333 g_param_spec_boxed ("numbers_font_desc",
335 _("Font description to use for the "
337 PANGO_TYPE_FONT_DESCRIPTION,
339 g_object_class_install_property (object_class,
341 g_param_spec_uint ("print_numbers",
342 _("Print Line Numbers"),
343 _("Interval of printed line numbers "
344 "(0 means no numbers)"),
347 g_object_class_install_property (object_class,
349 g_param_spec_boolean ("print_header",
351 _("Whether to print a header "
355 g_object_class_install_property (object_class,
357 g_param_spec_boolean ("print_footer",
359 _("Whether to print a footer "
363 g_object_class_install_property (object_class,
364 PROP_HEADER_FOOTER_FONT,
365 g_param_spec_string ("header_footer_font",
366 _("Header and Footer Font"),
367 _("GnomeFont name to use for the header "
368 "and footer (deprecated)"),
371 g_object_class_install_property (object_class,
372 PROP_HEADER_FOOTER_FONT_DESC,
373 g_param_spec_boxed ("header_footer_font_desc",
374 _("Header and Footer Font Description"),
375 _("Font to use for headers and footers "
376 "(e.g. \"Monospace 10\")"),
377 PANGO_TYPE_FONT_DESCRIPTION,
380 print_job_signals [BEGIN_PAGE] =
381 g_signal_new ("begin_page",
382 G_OBJECT_CLASS_TYPE (object_class),
384 G_STRUCT_OFFSET (GtkSourcePrintJobClass, begin_page),
386 g_cclosure_marshal_VOID__VOID,
389 print_job_signals [FINISHED] =
390 g_signal_new ("finished",
391 G_OBJECT_CLASS_TYPE (object_class),
393 G_STRUCT_OFFSET (GtkSourcePrintJobClass, finished),
395 g_cclosure_marshal_VOID__VOID,
401 gtk_source_print_job_instance_init (GtkSourcePrintJob *job)
403 GtkSourcePrintJobPrivate *priv;
405 priv = g_new0 (GtkSourcePrintJobPrivate, 1);
408 /* default job configuration */
412 priv->tabs_width = 8;
413 priv->wrap_mode = GTK_WRAP_NONE;
414 priv->highlight = TRUE;
415 priv->language = gtk_get_default_language ();
417 priv->numbers_font = NULL;
418 priv->print_numbers = 1;
419 priv->margin_top = 0.0;
420 priv->margin_bottom = 0.0;
421 priv->margin_left = 0.0;
422 priv->margin_right = 0.0;
424 priv->print_header = FALSE;
425 priv->print_footer = FALSE;
426 priv->header_footer_font = NULL;
427 priv->header_format_left = NULL;
428 priv->header_format_center = NULL;
429 priv->header_format_right = NULL;
430 priv->header_separator = FALSE;
431 priv->footer_format_left = NULL;
432 priv->footer_format_center = NULL;
433 priv->footer_format_right = NULL;
434 priv->footer_separator = FALSE;
437 priv->printing = FALSE;
438 priv->print_ctxt = NULL;
439 priv->print_job = NULL;
441 priv->page_count = 0;
443 priv->first_line_number = 0;
444 priv->paragraphs = NULL;
445 priv->tag_styles = NULL;
447 /* some default, sane values */
448 priv->page_width = A4_WIDTH;
449 priv->page_height = A4_HEIGHT;
450 priv->doc_margin_top = CM (1);
451 priv->doc_margin_left = CM (1);
452 priv->doc_margin_right = CM (1);
453 priv->doc_margin_bottom = CM (1);
457 free_paragraphs (GSList *paras)
459 while (paras != NULL)
461 Paragraph *para = paras->data;
462 TextSegment *seg = para->segment;
465 TextSegment *next = seg->next;
471 paras = g_slist_delete_link (paras, paras);
476 gtk_source_print_job_finalize (GObject *object)
478 GtkSourcePrintJob *job;
479 GtkSourcePrintJobPrivate *priv;
481 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (object));
483 job = GTK_SOURCE_PRINT_JOB (object);
488 if (priv->config != NULL)
489 gnome_print_config_unref (priv->config);
490 if (priv->buffer != NULL)
491 g_object_unref (priv->buffer);
492 if (priv->font != NULL)
493 pango_font_description_free (priv->font);
494 if (priv->numbers_font != NULL)
495 pango_font_description_free (priv->numbers_font);
496 if (priv->header_footer_font != NULL)
497 pango_font_description_free (priv->header_footer_font);
498 g_free (priv->header_format_left);
499 g_free (priv->header_format_right);
500 g_free (priv->header_format_center);
501 g_free (priv->footer_format_left);
502 g_free (priv->footer_format_right);
503 g_free (priv->footer_format_center);
505 if (priv->print_ctxt != NULL)
506 g_object_unref (priv->print_ctxt);
507 if (priv->print_job != NULL)
508 g_object_unref (priv->print_job);
509 if (priv->pango_context != NULL)
510 g_object_unref (priv->pango_context);
511 if (priv->tab_array != NULL)
512 pango_tab_array_free (priv->tab_array);
514 if (priv->paragraphs != NULL)
515 free_paragraphs (priv->paragraphs);
516 if (priv->tag_styles != NULL)
517 g_hash_table_destroy (priv->tag_styles);
523 G_OBJECT_CLASS (parent_class)->finalize (object);
527 gtk_source_print_job_get_property (GObject *object,
532 GtkSourcePrintJob *job = GTK_SOURCE_PRINT_JOB (object);
537 g_value_set_object (value, job->priv->config);
541 g_value_set_object (value, job->priv->buffer);
544 case PROP_TABS_WIDTH:
545 g_value_set_uint (value, job->priv->tabs_width);
549 g_value_set_enum (value, job->priv->wrap_mode);
553 g_value_set_boolean (value, job->priv->highlight);
557 g_value_take_string (value, gtk_source_print_job_get_font (job));
561 g_value_set_boxed (value, gtk_source_print_job_get_font_desc (job));
564 case PROP_NUMBERS_FONT:
565 g_value_take_string (value, gtk_source_print_job_get_numbers_font (job));
568 case PROP_NUMBERS_FONT_DESC:
569 g_value_set_boxed (value, gtk_source_print_job_get_numbers_font_desc (job));
572 case PROP_PRINT_NUMBERS:
573 g_value_set_uint (value, job->priv->print_numbers);
576 case PROP_PRINT_HEADER:
577 g_value_set_boolean (value, job->priv->print_header);
580 case PROP_PRINT_FOOTER:
581 g_value_set_boolean (value, job->priv->print_footer);
584 case PROP_HEADER_FOOTER_FONT:
585 g_value_take_string (value,
586 gtk_source_print_job_get_header_footer_font (job));
589 case PROP_HEADER_FOOTER_FONT_DESC:
590 g_value_set_boxed (value,
591 gtk_source_print_job_get_header_footer_font_desc (job));
595 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
601 gtk_source_print_job_set_property (GObject *object,
606 GtkSourcePrintJob *job = GTK_SOURCE_PRINT_JOB (object);
611 gtk_source_print_job_set_config (job, g_value_get_object (value));
615 gtk_source_print_job_set_buffer (job, g_value_get_object (value));
618 case PROP_TABS_WIDTH:
619 gtk_source_print_job_set_tabs_width (job, g_value_get_uint (value));
623 gtk_source_print_job_set_wrap_mode (job, g_value_get_enum (value));
627 gtk_source_print_job_set_highlight (job, g_value_get_boolean (value));
631 gtk_source_print_job_set_font (job, g_value_get_string (value));
635 gtk_source_print_job_set_font_desc (job, g_value_get_boxed (value));
638 case PROP_NUMBERS_FONT:
639 gtk_source_print_job_set_numbers_font (job, g_value_get_string (value));
642 case PROP_NUMBERS_FONT_DESC:
643 gtk_source_print_job_set_numbers_font_desc (job, g_value_get_boxed (value));
646 case PROP_PRINT_NUMBERS:
647 gtk_source_print_job_set_print_numbers (job, g_value_get_uint (value));
650 case PROP_PRINT_HEADER:
651 gtk_source_print_job_set_print_header (job, g_value_get_boolean (value));
654 case PROP_PRINT_FOOTER:
655 gtk_source_print_job_set_print_footer (job, g_value_get_boolean (value));
658 case PROP_HEADER_FOOTER_FONT:
659 gtk_source_print_job_set_header_footer_font (job,
660 g_value_get_string (value));
663 case PROP_HEADER_FOOTER_FONT_DESC:
664 gtk_source_print_job_set_header_footer_font_desc (job,
665 g_value_get_boxed (value));
669 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
675 gtk_source_print_job_begin_page (GtkSourcePrintJob *job)
677 g_return_if_fail (job->priv->printing);
679 if (job->priv->print_header && job->priv->header_height > 0)
683 x = job->priv->doc_margin_left + job->priv->margin_left;
684 y = job->priv->page_height - job->priv->doc_margin_top - job->priv->margin_top;
685 default_print_header (job, x, y);
688 if (job->priv->print_footer && job->priv->footer_height > 0)
692 x = job->priv->doc_margin_left + job->priv->margin_left;
693 y = job->priv->doc_margin_bottom +
694 job->priv->margin_bottom +
695 job->priv->footer_height;
696 default_print_footer (job, x, y);
700 /* ---- gnome-print / Pango convenience functions */
702 /* Gets the width of a layout in gnome-print coordinates */
704 get_layout_width (PangoLayout *layout)
708 pango_layout_get_size (layout, &layout_width, NULL);
709 return (gdouble) layout_width / PANGO_SCALE;
712 /* Gets the ascent/descent of a font in gnome-print coordinates */
714 get_font_ascent_descent (GtkSourcePrintJob *job,
715 PangoFontDescription *desc,
719 PangoFontMetrics *metrics;
721 metrics = pango_context_get_metrics (job->priv->pango_context,
723 job->priv->language);
726 *ascent = (gdouble) pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
728 *descent = (gdouble) pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
730 pango_font_metrics_unref (metrics);
733 /* Draws the first line in a layout; we use this for one-line layouts
734 * to get baseline alignment */
736 show_first_layout_line (GnomePrintContext *print_ctxt,
739 PangoLayoutLine *line;
741 line = pango_layout_get_lines (layout)->data;
742 gnome_print_pango_layout_line (print_ctxt, line);
746 get_line_number_layout (GtkSourcePrintJob *job,
752 num_str = g_strdup_printf ("%d", line_number);
753 layout = pango_layout_new (job->priv->pango_context);
754 pango_layout_set_font_description (layout, job->priv->numbers_font);
755 pango_layout_set_text (layout, num_str, -1);
761 /* ---- Configuration functions */
764 ensure_print_config (GtkSourcePrintJob *job)
766 if (job->priv->config == NULL)
767 job->priv->config = gnome_print_config_default ();
768 if (job->priv->font == NULL)
769 job->priv->font = pango_font_description_from_string (DEFAULT_FONT_NAME);
773 update_page_size_and_margins (GtkSourcePrintJob *job)
776 gdouble ascent, descent;
778 gnome_print_job_get_page_size_from_config (job->priv->config,
779 &job->priv->page_width,
780 &job->priv->page_height);
782 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_TOP,
783 &job->priv->doc_margin_top, NULL);
784 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM,
785 &job->priv->doc_margin_bottom, NULL);
786 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_LEFT,
787 &job->priv->doc_margin_left, NULL);
788 gnome_print_config_get_length (job->priv->config, GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT,
789 &job->priv->doc_margin_right, NULL);
791 /* set default fonts for numbers and header/footer */
792 if (job->priv->numbers_font == NULL)
793 job->priv->numbers_font = pango_font_description_copy (job->priv->font);
795 if (job->priv->header_footer_font == NULL)
796 job->priv->header_footer_font = pango_font_description_copy (job->priv->font);
798 /* calculate numbers width */
799 if (job->priv->print_numbers > 0)
801 layout = get_line_number_layout (job, job->priv->last_line_number);
802 job->priv->numbers_width = get_layout_width (layout) + NUMBERS_TEXT_SEPARATION;
803 g_object_unref (layout);
806 job->priv->numbers_width = 0.0;
808 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
810 /* calculate header/footer height */
811 if (job->priv->print_header &&
812 (job->priv->header_format_left != NULL ||
813 job->priv->header_format_center != NULL ||
814 job->priv->header_format_right != NULL))
815 job->priv->header_height = HEADER_FOOTER_SIZE * (ascent + descent);
817 job->priv->header_height = 0.0;
819 if (job->priv->print_footer &&
820 (job->priv->footer_format_left != NULL ||
821 job->priv->footer_format_center != NULL ||
822 job->priv->footer_format_right != NULL))
823 job->priv->footer_height = HEADER_FOOTER_SIZE * (ascent + descent);
825 job->priv->footer_height = 0.0;
827 /* verify that the user provided margins are not too excesive
828 * and that we still have room for the text */
829 job->priv->text_width = (job->priv->page_width -
830 job->priv->doc_margin_left - job->priv->doc_margin_right -
831 job->priv->margin_left - job->priv->margin_right -
832 job->priv->numbers_width);
834 job->priv->text_height = (job->priv->page_height -
835 job->priv->doc_margin_top - job->priv->doc_margin_bottom -
836 job->priv->margin_top - job->priv->margin_bottom -
837 job->priv->header_height - job->priv->footer_height);
839 /* FIXME: put some saner values than 5cm - Gustavo */
840 g_return_val_if_fail (job->priv->text_width > CM(5.0), FALSE);
841 g_return_val_if_fail (job->priv->text_height > CM(5.0), FALSE);
846 /* We want a uniform tab width for the entire job without regard to style
847 * See comments in gtksourceview.c:calculate_real_tab_width
850 calculate_real_tab_width (GtkSourcePrintJob *job, guint tab_size, gchar c)
859 tab_string = g_strnfill (tab_size, c);
860 layout = pango_layout_new (job->priv->pango_context);
861 pango_layout_set_text (layout, tab_string, -1);
864 pango_layout_get_size (layout, &tab_width, NULL);
865 g_object_unref (G_OBJECT (layout));
871 setup_pango_context (GtkSourcePrintJob *job)
873 PangoFontMap *font_map;
876 if (!job->priv->pango_context)
878 font_map = gnome_print_pango_get_default_font_map ();
879 job->priv->pango_context = gnome_print_pango_create_context (font_map);
882 pango_context_set_language (job->priv->pango_context, job->priv->language);
883 pango_context_set_font_description (job->priv->pango_context, job->priv->font);
885 if (job->priv->tab_array)
887 pango_tab_array_free (job->priv->tab_array);
888 job->priv->tab_array = NULL;
891 real_tab_width = calculate_real_tab_width (job, job->priv->tabs_width, ' ');
892 if (real_tab_width > 0)
894 job->priv->tab_array = pango_tab_array_new (1, FALSE);
895 pango_tab_array_set_tab (job->priv->tab_array, 0, PANGO_TAB_LEFT, real_tab_width);
901 /* ----- Helper functions */
904 font_description_to_gnome_font_name (PangoFontDescription *desc)
906 GnomeFontFace *font_face;
909 /* Will always return some font */
910 font_face = gnome_font_face_find_closest_from_pango_description (desc);
912 retval = g_strdup_printf("%s %f",
913 gnome_font_face_get_name (font_face),
914 (double) pango_font_description_get_size (desc) / PANGO_SCALE);
915 g_object_unref (font_face);
921 * The following routines are duplicated in gedit/gedit/gedit-prefs-manager.c
924 /* Do this ourselves since gnome_font_find_closest() doesn't call
925 * gnome_font_face_find_closest() (probably a gnome-print bug)
928 face_and_size_from_full_name (const guchar *name,
929 GnomeFontFace **face,
935 copy = g_strdup (name);
936 str_size = strrchr (copy, ' ');
941 *size = atof (str_size);
948 *face = gnome_font_face_find_closest (copy);
952 static PangoFontDescription *
953 font_description_from_gnome_font_name (const char *font_name)
956 PangoFontDescription *desc;
961 face_and_size_from_full_name (font_name, &face, &size);
963 /* Pango and GnomePrint have basically the same numeric weight values */
964 weight = (PangoWeight) gnome_font_face_get_weight_code (face);
965 style = gnome_font_face_is_italic (face) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL;
967 desc = pango_font_description_new ();
968 pango_font_description_set_family (desc, gnome_font_face_get_family_name (face));
969 pango_font_description_set_weight (desc, weight);
970 pango_font_description_set_style (desc, style);
971 pango_font_description_set_size (desc, size * PANGO_SCALE);
973 g_object_unref (face);
978 /* ---- TextStyle functions */
981 text_style_new (GtkSourcePrintJob *job, GtkTextTag *tag)
984 gboolean bg_set, fg_set;
986 PangoFontDescription *font_desc;
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;
1122 /* make sure the region to print is highlighted */
1123 /*_gtk_source_buffer_highlight_region (job->priv->buffer, start, end, TRUE); */
1125 next_toggle = *start;
1126 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1128 /* FIXME: handle invisible text properly. This also assumes
1129 * the text has no embedded images and stuff */
1130 while (gtk_text_iter_compare (start, end) < 0)
1136 para = g_new0 (Paragraph, 1);
1138 /* get the style at the start of the line */
1139 style = get_style (job, start);
1141 /* get a line of text - limit points to the end of the line */
1143 if (!gtk_text_iter_ends_line (&limit))
1144 gtk_text_iter_forward_to_line_end (&limit);
1146 if (gtk_text_iter_compare (&limit, end) > 0)
1149 /* create the first segment for the line */
1150 para->segment = seg = g_new0 (TextSegment, 1);
1153 /* while the next tag toggle is within the line, we check to see
1154 * if the style has changed at each tag toggle position, and if so,
1155 * create new segments */
1156 while (have_toggle && gtk_text_iter_compare (&next_toggle, &limit) < 0)
1158 /* check style changes */
1159 style = get_style (job, &next_toggle);
1160 if (style != seg->style)
1162 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 *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);
1183 /* add the line of text to the job */
1184 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1186 /* advance to next line */
1188 gtk_text_iter_forward_line (start);
1190 if (gtk_text_iter_compare (&next_toggle, start) < 0) {
1191 next_toggle = *start;
1192 have_toggle = gtk_text_iter_forward_to_tag_toggle (&next_toggle, NULL);
1195 job->priv->paragraphs = g_slist_reverse (job->priv->paragraphs);
1201 get_text_to_print (GtkSourcePrintJob *job,
1202 const GtkTextIter *start,
1203 const GtkTextIter *end)
1205 GtkTextIter _start, _end;
1208 g_return_val_if_fail (start != NULL && end != NULL, FALSE);
1209 g_return_val_if_fail (job->priv->buffer != NULL, FALSE);
1214 /* erase any previous data */
1215 if (job->priv->paragraphs != NULL)
1217 free_paragraphs (job->priv->paragraphs);
1218 job->priv->paragraphs = NULL;
1220 if (job->priv->tag_styles != NULL)
1222 g_hash_table_destroy (job->priv->tag_styles);
1223 job->priv->tag_styles = NULL;
1226 /* provide ordered iters */
1227 gtk_text_iter_order (&_start, &_end);
1229 /* save the first and last line numbers for future reference */
1230 job->priv->first_line_number = gtk_text_iter_get_line (&_start) + 1;
1231 job->priv->last_line_number = gtk_text_iter_get_line (&_end) + 1;
1233 if (!job->priv->highlight)
1234 retval = get_text_simple (job, &_start, &_end);
1236 retval = get_text_with_style (job, &_start, &_end);
1238 if (retval && job->priv->paragraphs == NULL)
1243 /* add an empty line to allow printing empty documents */
1244 seg = g_new0 (TextSegment, 1);
1246 seg->style = NULL; /* use default style */
1247 seg->text = g_strdup ("");
1249 para = g_new0 (Paragraph, 1);
1250 para->segment = seg;
1252 job->priv->paragraphs = g_slist_prepend (job->priv->paragraphs, para);
1258 /* ----- Pagination functions */
1261 add_attribute_to_list (PangoAttribute *attr,
1262 PangoAttrList *list,
1266 attr->start_index = index;
1267 attr->end_index = index + len;
1268 pango_attr_list_insert (list, attr);
1271 static PangoLayout *
1272 create_layout_for_para (GtkSourcePrintJob *job,
1276 PangoLayout *layout;
1277 PangoAttrList *attrs;
1281 text = g_string_new (NULL);
1282 attrs = pango_attr_list_new ();
1284 seg = para->segment;
1289 gsize seg_len = strlen (seg->text);
1290 g_string_append (text, seg->text);
1294 PangoAttribute *attr;
1296 attr = pango_attr_font_desc_new (seg->style->font_desc);
1297 add_attribute_to_list (attr, attrs, index, seg_len);
1299 if (seg->style->scale != PANGO_SCALE_MEDIUM)
1301 attr = pango_attr_scale_new (seg->style->scale);
1302 add_attribute_to_list (attr, attrs, index, seg_len);
1305 if (seg->style->foreground)
1307 attr = pango_attr_foreground_new (seg->style->foreground->red,
1308 seg->style->foreground->green,
1309 seg->style->foreground->blue);
1310 add_attribute_to_list (attr, attrs, index, seg_len);
1313 if (seg->style->background)
1315 attr = pango_attr_background_new (seg->style->background->red,
1316 seg->style->background->green,
1317 seg->style->background->blue);
1318 add_attribute_to_list (attr, attrs, index, seg_len);
1321 if (seg->style->strikethrough)
1323 attr = pango_attr_strikethrough_new (TRUE);
1324 add_attribute_to_list (attr, attrs, index, seg_len);
1327 if (seg->style->underline != PANGO_UNDERLINE_NONE)
1329 attr = pango_attr_underline_new (seg->style->underline);
1330 add_attribute_to_list (attr, attrs, index, seg_len);
1338 layout = pango_layout_new (job->priv->pango_context);
1340 /* if (job->priv->wrap_mode != GTK_WRAP_NONE)*/
1341 pango_layout_set_width (layout, job->priv->text_width * PANGO_SCALE);
1343 switch (job->priv->wrap_mode) {
1345 pango_layout_set_wrap (layout, PANGO_WRAP_CHAR);
1348 pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
1350 case GTK_WRAP_WORD_CHAR:
1351 pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
1355 * Ellipsize the paragraph when text wrapping is disabled.
1356 * Another possibility would be to set the width so the text
1357 * breaks into multiple lines, and paginate/render just the
1359 * See also Comment #23 by Owen on bug #143874.
1362 /* orph says to comment this out and commit it.
1363 PANGO_ELLIPSIZE_END is not available in pango
1364 1.4.1, at least, and he says this code is never
1366 /*pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);*/
1371 if (job->priv->tab_array)
1372 pango_layout_set_tabs (layout, job->priv->tab_array);
1374 pango_layout_set_text (layout, text->str, text->len);
1375 pango_layout_set_attributes (layout, attrs);
1377 /* FIXME: <horrible-hack>
1378 * For empty paragraphs, pango_layout_iter_get_baseline() returns 0,
1379 * so I check this condition and add a space character to force
1380 * the calculation of the baseline. I don't like that, but I
1381 * didn't find a better way to do it. Note that a paragraph is
1382 * considered empty either when it has no characters, or when
1384 * See comment #22 and #23 on bug #143874.
1386 if (job->priv->print_numbers > 0)
1388 PangoLayoutIter *iter;
1389 iter = pango_layout_get_iter (layout);
1390 if (pango_layout_iter_get_baseline (iter) == 0)
1392 g_string_append_c (text, ' ');
1393 pango_layout_set_text (layout, text->str, text->len);
1395 pango_layout_iter_free (iter);
1397 /* FIXME: </horrible-hack> */
1399 g_string_free (text, TRUE);
1400 pango_attr_list_unref (attrs);
1405 /* The break logic in this function needs to match that in print_paragraph */
1407 paginate_paragraph (GtkSourcePrintJob *job,
1410 PangoLayout *layout;
1411 PangoLayoutIter *iter;
1412 PangoRectangle logical_rect;
1416 layout = create_layout_for_para (job, para);
1418 iter = pango_layout_get_iter (layout);
1425 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
1426 max = (gdouble) (logical_rect.y + logical_rect.height) / PANGO_SCALE;
1428 if (max - page_skip > job->priv->available_height)
1430 /* "create" a new page */
1431 job->priv->page_count++;
1432 job->priv->available_height = job->priv->text_height;
1433 page_skip = (gdouble) logical_rect.y / PANGO_SCALE;
1437 while (pango_layout_iter_next_line (iter));
1439 job->priv->available_height -= max - page_skip;
1441 pango_layout_iter_free (iter);
1442 g_object_unref (layout);
1446 paginate_text (GtkSourcePrintJob *job)
1451 /* set these to zero so the first break_line creates a new page */
1452 job->priv->page_count = 0;
1453 job->priv->available_height = 0;
1454 line_number = job->priv->first_line_number;
1455 l = job->priv->paragraphs;
1458 Paragraph *para = l->data;
1460 para->line_number = line_number;
1461 paginate_paragraph (job, para);
1464 l = g_slist_next (l);
1467 /* FIXME: do we have any error condition which can force us to
1468 * return %FALSE? - Gustavo */
1472 /* ---- Printing functions */
1475 begin_page (GtkSourcePrintJob *job)
1477 gnome_print_beginpage (job->priv->print_ctxt, NULL);
1479 g_signal_emit (job, print_job_signals [BEGIN_PAGE], 0);
1483 end_page (GtkSourcePrintJob *job)
1485 gnome_print_showpage (job->priv->print_ctxt);
1489 print_line_number (GtkSourcePrintJob *job,
1494 PangoLayout *layout;
1496 layout = get_line_number_layout (job, line_number);
1498 x = x + job->priv->numbers_width - get_layout_width (layout) - NUMBERS_TEXT_SEPARATION;
1499 gnome_print_moveto (job->priv->print_ctxt, x, y);
1501 show_first_layout_line (job->priv->print_ctxt, layout);
1503 g_object_unref (layout);
1506 /* The break logic in this function needs to match that in paginate_paragraph
1508 * @start_line is the first line in the paragraph to print
1509 * @y is updated to the position after the portion of the paragraph we printed
1510 * @baseline_out is set to the baseline of the first line of the paragraph
1511 * if we printed it. (And not set otherwise)
1513 * Returns the first unprinted line in the paragraph (unprinted because it
1514 * flowed onto the next page) or -1 if the entire paragraph was printed.
1517 print_paragraph (GtkSourcePrintJob *job,
1522 gdouble *baseline_out,
1525 PangoLayout *layout;
1526 PangoLayoutIter *iter;
1527 PangoRectangle logical_rect;
1534 layout = create_layout_for_para (job, para);
1536 iter = pango_layout_get_iter (layout);
1538 /* Skip over lines already printed on previous page(s) */
1539 for (current_line = 0; current_line < start_line; current_line++)
1540 pango_layout_iter_next_line (iter);
1547 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
1548 max = (gdouble) (logical_rect.y + logical_rect.height) / PANGO_SCALE;
1550 if (current_line == start_line)
1551 page_skip = (gdouble) logical_rect.y / PANGO_SCALE;
1553 if (max - page_skip > job->priv->available_height)
1555 result = current_line; /* Save position for next page */
1559 baseline = (gdouble) pango_layout_iter_get_baseline (iter) / PANGO_SCALE;
1560 baseline = *y + page_skip - baseline; /* Adjust to global coordinates */
1561 if (current_line == 0)
1562 *baseline_out = baseline;
1564 gnome_print_moveto (job->priv->print_ctxt,
1565 x + (gdouble) logical_rect.x / PANGO_SCALE,
1567 gnome_print_pango_layout_line (job->priv->print_ctxt,
1568 pango_layout_iter_get_line (iter));
1572 while (pango_layout_iter_next_line (iter));
1574 job->priv->available_height -= max - page_skip;
1575 *y -= max - page_skip;
1577 pango_layout_iter_free (iter);
1578 g_object_unref (layout);
1584 print_page (GtkSourcePrintJob *job)
1589 gboolean force_fit = TRUE;
1595 job->priv->available_height = job->priv->text_height;
1597 y = job->priv->page_height -
1598 job->priv->doc_margin_top - job->priv->margin_top -
1599 job->priv->header_height;
1600 x = job->priv->doc_margin_left + job->priv->margin_left +
1601 job->priv->numbers_width;
1602 l = job->priv->current_paragraph;
1603 line = job->priv->current_paragraph_line;
1607 Paragraph *para = l->data;
1609 gint last_line = line;
1611 line = print_paragraph (job, para, line, x, &y, &baseline, force_fit);
1613 if (last_line == 0 && line != 0)
1615 /* We printed the first line of a paragraph */
1616 if (job->priv->print_numbers > 0 &&
1617 ((para->line_number % job->priv->print_numbers) == 0))
1618 print_line_number (job,
1620 job->priv->doc_margin_left +
1621 job->priv->margin_left,
1624 job->priv->printed_lines++;
1628 break; /* Didn't all fit on this page */
1635 job->priv->current_paragraph = l;
1636 job->priv->current_paragraph_line = line;
1640 setup_for_print (GtkSourcePrintJob *job)
1642 job->priv->current_paragraph = job->priv->paragraphs;
1643 job->priv->page = 0;
1644 job->priv->printed_lines = 0;
1646 if (job->priv->print_job != NULL)
1647 g_object_unref (job->priv->print_job);
1648 if (job->priv->print_ctxt != NULL)
1649 g_object_unref (job->priv->print_ctxt);
1651 job->priv->print_job = gnome_print_job_new (job->priv->config);
1652 job->priv->print_ctxt = gnome_print_job_get_context (job->priv->print_job);
1654 gnome_print_pango_update_context (job->priv->pango_context, job->priv->print_ctxt);
1658 print_job (GtkSourcePrintJob *job)
1660 while (job->priv->current_paragraph != NULL)
1663 gnome_print_job_close (job->priv->print_job);
1667 idle_printing_handler (GtkSourcePrintJob *job)
1669 g_assert (job->priv->current_paragraph != NULL);
1673 if (job->priv->current_paragraph == NULL)
1675 gnome_print_job_close (job->priv->print_job);
1676 job->priv->printing = FALSE;
1677 job->priv->idle_printing_tag = 0;
1679 g_signal_emit (job, print_job_signals [FINISHED], 0);
1680 /* after this the print job object is possibly
1681 * destroyed (common use case) */
1689 /* Public API ------------------- */
1692 * gtk_source_print_job_new:
1693 * @config: an optional #GnomePrintConfig object.
1695 * Creates a new print job object, initially setting the print configuration.
1697 * Return value: the new print job object.
1700 gtk_source_print_job_new (GnomePrintConfig *config)
1702 GtkSourcePrintJob *job;
1704 g_return_val_if_fail (config == NULL || GNOME_IS_PRINT_CONFIG (config), NULL);
1706 job = GTK_SOURCE_PRINT_JOB (g_object_new (GTK_TYPE_SOURCE_PRINT_JOB, NULL));
1708 gtk_source_print_job_set_config (job, config);
1714 * gtk_source_print_job_new_with_buffer:
1715 * @config: an optional #GnomePrintConfig.
1716 * @buffer: the #GtkTextBuffer to print (might be %NULL).
1718 * Creates a new print job to print @buffer.
1720 * Return value: a new print job object.
1723 gtk_source_print_job_new_with_buffer (GnomePrintConfig *config,
1724 GtkTextBuffer *buffer)
1726 GtkSourcePrintJob *job;
1728 g_return_val_if_fail (config == NULL || GNOME_IS_PRINT_CONFIG (config), NULL);
1729 g_return_val_if_fail (buffer == NULL || GTK_IS_TEXT_BUFFER (buffer), NULL);
1731 job = gtk_source_print_job_new (config);
1733 gtk_source_print_job_set_buffer (job, buffer);
1738 /* --- print job basic configuration */
1741 * gtk_source_print_job_set_config:
1742 * @job: a #GtkSourcePrintJob.
1743 * @config: a #GnomePrintConfig object to get printing configuration from.
1745 * Sets the print configuration for the job. If you don't set a
1746 * configuration object for the print job, when needed one will be
1747 * created with gnome_print_config_default().
1750 gtk_source_print_job_set_config (GtkSourcePrintJob *job,
1751 GnomePrintConfig *config)
1753 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1754 g_return_if_fail (GNOME_IS_PRINT_CONFIG (config));
1755 g_return_if_fail (!job->priv->printing);
1757 if (config == job->priv->config)
1760 if (job->priv->config != NULL)
1761 gnome_print_config_unref (job->priv->config);
1763 job->priv->config = config;
1764 gnome_print_config_ref (config);
1766 g_object_notify (G_OBJECT (job), "config");
1770 * gtk_source_print_job_get_config:
1771 * @job: a #GtkSourcePrintJob.
1773 * Gets the current #GnomePrintConfig the print job will use. If not
1774 * previously set, this will create a default configuration and return
1775 * it. The returned object reference is owned by the print job.
1777 * Return value: the #GnomePrintConfig for the print job.
1780 gtk_source_print_job_get_config (GtkSourcePrintJob *job)
1782 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
1784 ensure_print_config (job);
1786 return job->priv->config;
1790 * gtk_source_print_job_set_buffer:
1791 * @job: a #GtkSourcePrintJob.
1792 * @buffer: a #GtkTextBuffer.
1794 * Sets the #GtkTextBuffer the print job will print. You need to
1795 * specify a buffer to print, either by the use of this function or by
1796 * creating the print job with gtk_source_print_job_new_with_buffer().
1799 gtk_source_print_job_set_buffer (GtkSourcePrintJob *job,
1800 GtkTextBuffer *buffer)
1802 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1803 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1804 g_return_if_fail (!job->priv->printing);
1806 if (buffer == job->priv->buffer)
1809 if (job->priv->buffer != NULL)
1810 g_object_unref (job->priv->buffer);
1812 job->priv->buffer = buffer;
1813 g_object_ref (buffer);
1815 g_object_notify (G_OBJECT (job), "buffer");
1819 * gtk_source_print_job_get_buffer:
1820 * @job: a #GtkSourcePrintJob.
1822 * Gets the #GtkTextBuffer the print job would print. The returned
1823 * object reference (if non %NULL) is owned by the job object and
1824 * should not be unreferenced.
1826 * Return value: the #GtkTextBuffer to print.
1829 gtk_source_print_job_get_buffer (GtkSourcePrintJob *job)
1831 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
1833 return job->priv->buffer;
1836 /* --- print job layout and style configuration */
1839 * gtk_source_print_job_set_tabs_width:
1840 * @job: a #GtkSourcePrintJob.
1841 * @tabs_width: the number of equivalent spaces for a tabulation.
1843 * Sets the width (in equivalent spaces) of tabulations for the
1844 * printed text. The width in printing units will be calculated as
1845 * the width of a string containing @tabs_width spaces of the default
1846 * font. Tabulation stops are set for the full width of printed text.
1849 gtk_source_print_job_set_tabs_width (GtkSourcePrintJob *job,
1852 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1853 g_return_if_fail (!job->priv->printing);
1855 if (tabs_width == job->priv->tabs_width)
1858 job->priv->tabs_width = tabs_width;
1860 g_object_notify (G_OBJECT (job), "tabs_width");
1864 * gtk_source_print_job_get_tabs_width:
1865 * @job: a #GtkSourcePrintJob.
1867 * Determines the configured width (in equivalent spaces) of
1868 * tabulations. The default value is 8.
1870 * Return value: the width (in equivalent spaces) of a tabulation.
1873 gtk_source_print_job_get_tabs_width (GtkSourcePrintJob *job)
1875 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
1877 return job->priv->tabs_width;
1881 * gtk_source_print_job_set_wrap_mode:
1882 * @job: a #GtkSourcePrintJob.
1883 * @wrap: the wrap mode.
1885 * Sets the wrap mode for lines of text larger than the printable
1886 * width. See #GtkWrapMode for a definition of the possible values.
1889 gtk_source_print_job_set_wrap_mode (GtkSourcePrintJob *job,
1892 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1893 g_return_if_fail (!job->priv->printing);
1895 if (wrap == job->priv->wrap_mode)
1898 job->priv->wrap_mode = wrap;
1900 g_object_notify (G_OBJECT (job), "wrap_mode");
1904 * gtk_source_print_job_get_wrap_mode:
1905 * @job: a #GtkSourcePrintJob.
1907 * Determines the wrapping style for text lines wider than the
1908 * printable width. The default is no wrapping.
1910 * Return value: the current wrapping mode for the print job.
1913 gtk_source_print_job_get_wrap_mode (GtkSourcePrintJob *job)
1915 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), GTK_WRAP_NONE);
1917 return job->priv->wrap_mode;
1921 * gtk_source_print_job_set_highlight:
1922 * @job: a #GtkSourcePrintJob.
1923 * @highlight: %TRUE if the printed text should be highlighted.
1925 * Sets whether the printed text will be highlighted according to the
1926 * buffer rules. Both color and font style are applied.
1929 gtk_source_print_job_set_highlight (GtkSourcePrintJob *job,
1932 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1933 g_return_if_fail (!job->priv->printing);
1935 highlight = (highlight != FALSE);
1937 if (highlight == job->priv->highlight)
1940 job->priv->highlight = highlight;
1942 g_object_notify (G_OBJECT (job), "highlight");
1946 * gtk_source_print_job_get_highlight:
1947 * @job: a #GtkSourcePrintJob.
1949 * Determines if the job is configured to print the text highlighted
1950 * with colors and font styles. Note that highlighting will happen
1951 * only if the buffer to print has highlighting activated.
1953 * Return value: %TRUE if the printed output will be highlighted.
1956 gtk_source_print_job_get_highlight (GtkSourcePrintJob *job)
1958 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
1960 return job->priv->highlight;
1964 * gtk_source_print_job_set_font_desc:
1965 * @job: a #GtkSourcePrintJob.
1966 * @desc: the #PangoFontDescription for the default font
1968 * Sets the default font for the printed text.
1971 gtk_source_print_job_set_font_desc (GtkSourcePrintJob *job,
1972 PangoFontDescription *desc)
1974 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
1975 g_return_if_fail (desc != NULL);
1976 g_return_if_fail (!job->priv->printing);
1978 desc = pango_font_description_copy (desc);
1979 if (job->priv->font != NULL)
1980 pango_font_description_free (job->priv->font);
1981 job->priv->font = desc;
1982 g_object_freeze_notify (G_OBJECT (job));
1983 g_object_notify (G_OBJECT (job), "font");
1984 g_object_notify (G_OBJECT (job), "font_desc");
1985 g_object_thaw_notify (G_OBJECT (job));
1989 * gtk_source_print_job_set_font:
1990 * @job: a #GtkSourcePrintJob.
1991 * @font_name: the name of the default font.
1993 * Sets the default font for the printed text. @font_name should be a
1994 * <emphasis>full font name</emphasis> GnomePrint can understand
1995 * (e.g. "Monospace Regular 10.0").
1997 * Note that @font_name is a #GnomeFont name not a Pango font
1998 * description string. This function is deprecated since #GnomeFont is
1999 * no longer used when implementing printing for GtkSourceView; you
2000 * should use gtk_source_print_job_set_font_desc() instead.
2003 gtk_source_print_job_set_font (GtkSourcePrintJob *job,
2004 const gchar *font_name)
2006 PangoFontDescription *desc;
2008 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2009 g_return_if_fail (font_name != NULL);
2010 g_return_if_fail (!job->priv->printing);
2012 desc = font_description_from_gnome_font_name (font_name);
2015 gtk_source_print_job_set_font_desc (job, desc);
2016 pango_font_description_free (desc);
2021 * gtk_source_print_job_get_font_desc:
2022 * @job: a #GtkSourcePrintJob.
2024 * Determines the default font to be used for the printed text. The
2025 * returned string is of the form "Fontfamily Style Size",
2026 * for example "Monospace Regular 10.0". The returned value
2027 * should be freed when no longer needed.
2029 * Return value: the current text font description. This value is
2030 * owned by the job and must not be modified or freed.
2032 PangoFontDescription *
2033 gtk_source_print_job_get_font_desc (GtkSourcePrintJob *job)
2035 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2037 ensure_print_config (job);
2039 return job->priv->font;
2043 * gtk_source_print_job_get_font:
2044 * @job: a #GtkSourcePrintJob.
2046 * Determines the default font to be used for the printed text. The
2047 * returned string is of the form "Fontfamily Style Size",
2048 * for example "Monospace Regular 10.0". The returned value
2049 * should be freed when no longer needed.
2051 * Note that the result is a #GnomeFont name not a Pango font
2052 * description string. This function is deprecated since #GnomeFont is
2053 * no longer used when implementing printing for GtkSourceView; you
2054 * should use gtk_source_print_job_get_font_desc() instead.
2056 * Return value: a newly allocated string with the name of the current
2060 gtk_source_print_job_get_font (GtkSourcePrintJob *job)
2062 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2064 ensure_print_config (job);
2066 return font_description_to_gnome_font_name (job->priv->font);
2070 * gtk_source_print_job_setup_from_view:
2071 * @job: a #GtkSourcePrintJob.
2072 * @view: a #GtkSourceView to get configuration from.
2074 * Convenience function to set several configuration options at once,
2075 * so that the printed output matches @view. The options set are
2076 * buffer (if not set already), tabs width, highlighting, wrap mode
2080 gtk_source_print_job_setup_from_view (GtkSourcePrintJob *job,
2083 GtkTextBuffer *buffer = NULL;
2084 PangoContext *pango_context;
2086 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2087 g_return_if_fail (!job->priv->printing);
2089 buffer = gtk_text_view_get_buffer (view);
2091 if (job->priv->buffer == NULL && buffer != NULL)
2092 gtk_source_print_job_set_buffer (job, buffer);
2094 /* gtk_source_print_job_set_tabs_width (job, gtk_source_view_get_tabs_width (view)); */
2095 gtk_source_print_job_set_highlight (job, TRUE);
2096 gtk_source_print_job_set_wrap_mode (job, gtk_text_view_get_wrap_mode (view));
2098 pango_context = gtk_widget_get_pango_context (GTK_WIDGET (view));
2099 gtk_source_print_job_set_font_desc (job,
2100 pango_context_get_font_description (pango_context));
2104 * gtk_source_print_job_set_numbers_font_desc:
2105 * @job: a #GtkSourcePrintJob.
2106 * @desc: the #PangoFontDescription for the font for line numbers, or %NULL
2108 * Sets the font for printing line numbers on the left margin. If
2109 * NULL is supplied, the default font (i.e. the one being used for the
2110 * text) will be used instead.
2113 gtk_source_print_job_set_numbers_font_desc (GtkSourcePrintJob *job,
2114 PangoFontDescription *desc)
2116 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2117 g_return_if_fail (!job->priv->printing);
2120 desc = pango_font_description_copy (desc);
2121 if (job->priv->numbers_font != NULL)
2122 pango_font_description_free (job->priv->numbers_font);
2123 job->priv->numbers_font = desc;
2124 g_object_freeze_notify (G_OBJECT (job));
2125 g_object_notify (G_OBJECT (job), "numbers_font");
2126 g_object_notify (G_OBJECT (job), "numbers_font_desc");
2127 g_object_thaw_notify (G_OBJECT (job));
2131 * gtk_source_print_job_set_numbers_font:
2132 * @job: a #GtkSourcePrintJob.
2133 * @font_name: the full name of the font for line numbers, or %NULL.
2135 * Sets the font for printing line numbers on the left margin. If
2136 * %NULL is supplied, the default font (i.e. the one being used for the
2137 * text) will be used instead.
2139 * Note that @font_name is a #GnomeFont name not a Pango font
2140 * description string. This function is deprecated since #GnomeFont is
2141 * no longer used when implementing printing for GtkSourceView; you
2142 * should use gtk_source_print_job_set_numbers_font_desc() instead.
2145 gtk_source_print_job_set_numbers_font (GtkSourcePrintJob *job,
2146 const gchar *font_name)
2148 PangoFontDescription *desc;
2150 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2151 g_return_if_fail (!job->priv->printing);
2153 if (font_name != NULL)
2155 desc = font_description_from_gnome_font_name (font_name);
2158 gtk_source_print_job_set_numbers_font_desc (job, desc);
2159 pango_font_description_free (desc);
2163 gtk_source_print_job_set_numbers_font (job, NULL);
2167 * gtk_source_print_job_get_numbers_font_desc:
2168 * @job: a #GtkSourcePrintJob.
2170 * Determines the font to be used for the line numbers. This function
2171 * might return %NULL if a specific font for numbers has not been set.
2173 * Return value: the line numbers font description or %NULL. This value is
2174 * owned by the job and must not be modified or freed.
2176 PangoFontDescription *
2177 gtk_source_print_job_get_numbers_font_desc (GtkSourcePrintJob *job)
2179 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2181 return job->priv->numbers_font;
2185 * gtk_source_print_job_get_numbers_font:
2186 * @job: a #GtkSourcePrintJob.
2188 * Determines the font to be used for the line numbers. The returned
2189 * string is of the form "Fontfamily Style Size", for
2190 * example "Monospace Regular 10.0". The returned value
2191 * should be freed when no longer needed. This function might return
2192 * %NULL if a specific font for numbers has not been set.
2194 * Note that the result is a #GnomeFont name not a Pango font
2195 * description string. This function is deprecated since #GnomeFont is
2196 * no longer used when implementing printing for GtkSourceView; you
2197 * should use gtk_source_print_job_get_numbers_font_desc() instead.
2199 * Return value: a newly allocated string with the name of the current
2200 * line numbers font, or %NULL.
2203 gtk_source_print_job_get_numbers_font (GtkSourcePrintJob *job)
2205 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2207 if (job->priv->numbers_font != NULL)
2208 return font_description_to_gnome_font_name (job->priv->numbers_font);
2214 * gtk_source_print_job_set_print_numbers:
2215 * @job: a #GtkSourcePrintJob.
2216 * @interval: interval for printed line numbers.
2218 * Sets the interval for printed line numbers. If @interval is 0 no
2219 * numbers will be printed. If greater than 0, a number will be
2220 * printed every @interval lines (i.e. 1 will print all line numbers).
2223 gtk_source_print_job_set_print_numbers (GtkSourcePrintJob *job,
2226 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2227 g_return_if_fail (!job->priv->printing);
2229 if (interval == job->priv->print_numbers)
2232 job->priv->print_numbers = interval;
2234 g_object_notify (G_OBJECT (job), "print_numbers");
2238 * gtk_source_print_job_get_print_numbers:
2239 * @job: a #GtkSourcePrintJob.
2241 * Determines the interval used for line number printing. If the
2242 * value is 0, no line numbers will be printed. The default value is
2243 * 1 (i.e. numbers printed in all lines).
2245 * Return value: the interval of printed line numbers.
2248 gtk_source_print_job_get_print_numbers (GtkSourcePrintJob *job)
2250 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2252 return job->priv->print_numbers;
2256 * gtk_source_print_job_set_text_margins:
2257 * @job: a #GtkSourcePrintJob.
2258 * @top: the top user margin.
2259 * @bottom: the bottom user margin.
2260 * @left: the left user margin.
2261 * @right: the right user margin.
2263 * Sets the four user margins for the print job. These margins are in
2264 * addition to the document margins provided in the #GnomePrintConfig
2265 * and will not be used for headers, footers or line numbers (those
2266 * are calculated separatedly). You can print in the space allocated
2267 * by these margins by connecting to the <link
2268 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link> signal. The
2269 * space is around the printed text, and inside the margins specified
2270 * in the #GnomePrintConfig.
2272 * The margin numbers are given in device units. If any of the given
2273 * values is less than 0, that particular margin is not altered by
2277 gtk_source_print_job_set_text_margins (GtkSourcePrintJob *job,
2283 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2284 g_return_if_fail (!job->priv->printing);
2287 job->priv->margin_top = top;
2289 job->priv->margin_bottom = bottom;
2291 job->priv->margin_left = left;
2293 job->priv->margin_right = right;
2297 * gtk_source_print_job_get_text_margins:
2298 * @job: a #GtkSourcePrintJob.
2299 * @top: a pointer to a #gdouble to return the top margin.
2300 * @bottom: a pointer to a #gdouble to return the bottom margin.
2301 * @left: a pointer to a #gdouble to return the left margin.
2302 * @right: a pointer to a #gdouble to return the right margin.
2304 * Determines the user set margins for the job. This function
2305 * retrieves the values previously set by
2306 * gtk_source_print_job_set_text_margins(). The default for all four
2307 * margins is 0. Any of the pointers can be %NULL if you want to
2308 * ignore that value.
2311 gtk_source_print_job_get_text_margins (GtkSourcePrintJob *job,
2317 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2320 *top = job->priv->margin_top;
2322 *bottom = job->priv->margin_bottom;
2324 *left = job->priv->margin_left;
2326 *right = job->priv->margin_right;
2329 /* --- printing operations */
2332 gtk_source_print_job_prepare (GtkSourcePrintJob *job,
2333 const GtkTextIter *start,
2334 const GtkTextIter *end)
2336 PROFILE (GTimer *timer);
2338 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2339 g_return_val_if_fail (!job->priv->printing, FALSE);
2340 g_return_val_if_fail (job->priv->buffer != NULL, FALSE);
2341 g_return_val_if_fail (start != NULL && end != NULL, FALSE);
2343 /* make sure we have a sane configuration to start printing */
2344 ensure_print_config (job);
2346 PROFILE (timer = g_timer_new ());
2348 /* get the text to print */
2349 if (!get_text_to_print (job, start, end))
2352 PROFILE (g_message ("get_text_to_print: %.2f", g_timer_elapsed (timer, NULL)));
2354 if (!setup_pango_context (job))
2358 if (!update_page_size_and_margins (job))
2361 /* split the document in pages */
2362 if (!paginate_text (job))
2366 g_message ("paginate_text: %.2f", g_timer_elapsed (timer, NULL));
2367 g_timer_destroy (timer);
2374 * gtk_source_print_job_print:
2375 * @job: a configured #GtkSourcePrintJob.
2377 * Produces a #GnomePrintJob with the printed document. The whole
2378 * contents of the configured #GtkTextBuffer are printed. The
2379 * returned job is already closed and ready to be previewed (using
2380 * gnome_print_job_preview_new()) or printed directly. The caller of
2381 * this function owns a reference to the returned object, so @job can
2382 * be destroyed and the output will still be valid, or the document
2383 * can be printed again with different settings.
2385 * Return value: a closed #GnomePrintJob with the printed document, or
2386 * %NULL if printing could not be completed.
2389 gtk_source_print_job_print (GtkSourcePrintJob *job)
2391 GtkTextIter start, end;
2393 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2394 g_return_val_if_fail (!job->priv->printing, NULL);
2395 g_return_val_if_fail (job->priv->buffer != NULL, NULL);
2397 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (job->priv->buffer), &start, &end);
2399 return gtk_source_print_job_print_range (job, &start, &end);
2403 * gtk_source_print_job_print_range:
2404 * @job: a configured #GtkSourcePrintJob.
2405 * @start: the start of the region of text to print.
2406 * @end: the end of the region of text to print.
2408 * Similar to gtk_source_print_job_print(), except you can specify a
2409 * range of text to print. The passed #GtkTextIter values might be
2412 * Return value: a closed #GnomePrintJob with the text from @start to
2413 * @end printed, or %NULL if @job could not print.
2416 gtk_source_print_job_print_range (GtkSourcePrintJob *job,
2417 const GtkTextIter *start,
2418 const GtkTextIter *end)
2420 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2421 g_return_val_if_fail (!job->priv->printing, NULL);
2422 g_return_val_if_fail (job->priv->buffer != NULL, NULL);
2423 g_return_val_if_fail (start != NULL && end != NULL, NULL);
2424 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
2425 GTK_TEXT_BUFFER (job->priv->buffer) &&
2426 gtk_text_iter_get_buffer (end) ==
2427 GTK_TEXT_BUFFER (job->priv->buffer), NULL);
2429 if (!gtk_source_print_job_prepare (job, start, end))
2432 /* real work starts here */
2433 setup_for_print (job);
2435 job->priv->printing = TRUE;
2437 job->priv->printing = FALSE;
2439 g_object_ref (job->priv->print_job);
2440 return job->priv->print_job;
2443 /* --- asynchronous printing */
2446 * gtk_source_print_job_print_range_async:
2447 * @job: a configured #GtkSourcePrintJob.
2448 * @start: the start of the region of text to print.
2449 * @end: the end of the region of text to print.
2451 * Starts to print @job asynchronously. This function will ready the
2452 * @job for printing and install an idle handler that will render one
2455 * This function will not return immediatly, as only page rendering is
2456 * done asynchronously. Text retrieval and paginating happens within
2457 * this function. Also, if highlighting is enabled, the whole buffer
2458 * needs to be highlighted first.
2460 * To get notification when the job has finished, you must connect to
2462 * linkend="GtkSourcePrintJob-finished">"finished"</link>
2463 * signal. After this signal is emitted you can retrieve the
2464 * resulting #GnomePrintJob with gtk_source_print_job_get_print_job().
2465 * You may cancel the job with gtk_source_print_job_cancel().
2467 * Return value: %TRUE if the print started.
2470 gtk_source_print_job_print_range_async (GtkSourcePrintJob *job,
2471 const GtkTextIter *start,
2472 const GtkTextIter *end)
2474 GSource *idle_source;
2476 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2477 g_return_val_if_fail (!job->priv->printing, FALSE);
2478 g_return_val_if_fail (job->priv->buffer != NULL, FALSE);
2479 g_return_val_if_fail (start != NULL && end != NULL, FALSE);
2480 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
2481 GTK_TEXT_BUFFER (job->priv->buffer) &&
2482 gtk_text_iter_get_buffer (end) ==
2483 GTK_TEXT_BUFFER (job->priv->buffer), FALSE);
2485 if (!gtk_source_print_job_prepare (job, start, end))
2488 /* real work starts here */
2489 setup_for_print (job);
2490 if (job->priv->current_paragraph == NULL)
2493 /* setup the idle handler to print each page at a time */
2494 idle_source = g_idle_source_new ();
2495 g_source_set_priority (idle_source, GTK_SOURCE_PRINT_JOB_PRIORITY);
2496 g_source_set_closure (idle_source,
2497 g_cclosure_new_object ((GCallback) idle_printing_handler,
2499 job->priv->idle_printing_tag = g_source_attach (idle_source, NULL);
2500 g_source_unref (idle_source);
2502 job->priv->printing = TRUE;
2508 * gtk_source_print_job_cancel:
2509 * @job: a #GtkSourcePrintJob.
2511 * Cancels an asynchronous printing operation. This will remove any
2512 * pending print idle handler and unref the current #GnomePrintJob.
2514 * Note that if you got a reference to the job's #GnomePrintJob (using
2515 * gtk_source_print_job_get_print_job()) it will not be destroyed
2516 * (since you hold a reference to it), but it will not be closed
2517 * either. If you wish to show or print the partially printed
2518 * document you need to close it yourself.
2520 * This function has no effect when called from a non-asynchronous
2524 gtk_source_print_job_cancel (GtkSourcePrintJob *job)
2526 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2527 g_return_if_fail (job->priv->printing);
2529 if (job->priv->idle_printing_tag > 0)
2531 g_source_remove (job->priv->idle_printing_tag);
2532 job->priv->current_paragraph = NULL;
2533 job->priv->idle_printing_tag = 0;
2534 job->priv->printing = FALSE;
2535 g_object_unref (job->priv->print_job);
2536 g_object_unref (job->priv->print_ctxt);
2537 job->priv->print_job = NULL;
2538 job->priv->print_ctxt = NULL;
2543 * gtk_source_print_job_get_print_job:
2544 * @job: a #GtkSourcePrintJob.
2546 * Gets a reference to the #GnomePrintJob which the @job is printing
2547 * or has recently finished printing. You need to unref the returned
2550 * You may call this function in the middle of an asynchronous
2551 * printing operation, but the returned #GnomePrintJob will not be
2552 * closed until the last page is printed and the <link
2553 * linkend="GtkSourcePrintJob-finished">"finished"</link>
2554 * signal is emitted.
2556 * Return value: a new reference to the @job's #GnomePrintJob, or
2560 gtk_source_print_job_get_print_job (GtkSourcePrintJob *job)
2562 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2564 if (job->priv->print_job)
2565 g_object_ref (job->priv->print_job);
2567 return job->priv->print_job;
2570 /* --- information for asynchronous ops and headers and footers callback */
2573 * gtk_source_print_job_get_page:
2574 * @job: a #GtkSourcePrintJob.
2576 * Determines the currently printing page number. This function is
2577 * only valid while printing (either synchronously or asynchronously).
2579 * Return value: the current page number.
2582 gtk_source_print_job_get_page (GtkSourcePrintJob *job)
2584 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2585 g_return_val_if_fail (job->priv->printing, 0);
2587 return job->priv->page;
2591 * gtk_source_print_job_get_page_count:
2592 * @job: a #GtkSourcePrintJob.
2594 * Determines the total number of pages the job will print. The
2595 * returned value is only meaninful after pagination has finished. In
2596 * practice, for synchronous printing this means when <link
2597 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link>
2598 * is emitted, or after gtk_source_print_job_print_range_async() has
2601 * Return value: the number of pages of the printed job.
2604 gtk_source_print_job_get_page_count (GtkSourcePrintJob *job)
2606 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), 0);
2608 return job->priv->page_count;
2612 * gtk_source_print_job_get_print_context:
2613 * @job: a printing #GtkSourcePrintJob.
2615 * Determines the #GnomePrintContext of the current job. This
2616 * function is only valid while printing. Normally you would use this
2617 * function to print in the margins set by
2618 * gtk_source_print_job_set_margins() in a handler for the <link
2619 * linkend="GtkSourcePrintJob-begin-page">"begin_page"</link>
2622 * Return value: the current #GnomePrintContext. The returned object
2626 gtk_source_print_job_get_print_context (GtkSourcePrintJob *job)
2628 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
2629 g_return_val_if_fail (job->priv->printing, NULL);
2631 return job->priv->print_ctxt;
2634 /* ---- Header and footer (default implementation) */
2636 /* Most of this code taken from GLib's g_date_strftime() in gdate.c
2637 * GLIB - Library of useful routines for C programming
2638 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald */
2641 strdup_strftime (const gchar *format, const struct tm *tm)
2643 gsize locale_format_len = 0;
2644 gchar *locale_format;
2650 GError *error = NULL;
2652 g_return_val_if_fail (format != NULL, NULL);
2653 g_return_val_if_fail (tm != NULL, NULL);
2655 locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);
2659 g_warning (G_STRLOC "Error converting format to locale encoding: %s",
2661 g_error_free (error);
2666 tmpbufsize = MAX (128, locale_format_len * 2);
2669 tmpbuf = g_malloc (tmpbufsize);
2671 /* Set the first byte to something other than '\0', to be able to
2672 * recognize whether strftime actually failed or just returned "".
2675 tmplen = strftime (tmpbuf, tmpbufsize, locale_format, tm);
2677 if (tmplen == 0 && tmpbuf[0] != '\0')
2682 if (tmpbufsize > 65536)
2684 g_warning (G_STRLOC "Maximum buffer size for strdup_strftime "
2685 "exceeded: giving up");
2686 g_free (locale_format);
2693 g_free (locale_format);
2695 convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);
2700 g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s",
2702 g_error_free (error);
2711 evaluate_format_string (GtkSourcePrintJob *job, const gchar *format)
2714 gchar *eval_str, *retval;
2715 const struct tm *tm;
2721 tm = localtime (&now);
2723 /* analyze format string and replace the codes we know */
2724 eval = g_string_new_len (NULL, strlen (format));
2725 ch = g_utf8_get_char (format);
2730 format = g_utf8_next_char (format);
2731 ch = g_utf8_get_char (format);
2733 g_string_append_printf (eval, "%d", job->priv->page);
2735 g_string_append_printf (eval, "%d", job->priv->page_count);
2738 g_string_append_c (eval, '%');
2739 g_string_append_unichar (eval, ch);
2743 g_string_append_unichar (eval, ch);
2745 format = g_utf8_next_char (format);
2746 ch = g_utf8_get_char (format);
2749 eval_str = g_string_free (eval, FALSE);
2750 retval = strdup_strftime (eval_str, tm);
2757 print_header_footer_string (GtkSourcePrintJob *job,
2758 const gchar *format,
2763 PangoLayout *layout;
2768 width = job->priv->text_width + job->priv->numbers_width;
2770 text = evaluate_format_string (job, format);
2773 layout = pango_layout_new (job->priv->pango_context);
2774 pango_layout_set_font_description (layout, job->priv->header_footer_font);
2775 pango_layout_set_text (layout, text, -1);
2777 xx = x + x_align * (width - get_layout_width (layout));
2778 gnome_print_moveto (job->priv->print_ctxt, xx, y);
2779 show_first_layout_line (job->priv->print_ctxt, layout);
2782 g_object_unref (layout);
2787 default_print_header (GtkSourcePrintJob *job,
2793 gdouble ascent, descent;
2795 width = job->priv->text_width + job->priv->numbers_width;
2797 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
2802 if (job->priv->header_format_left != NULL)
2803 print_header_footer_string (job, job->priv->header_format_left, 0.0, x, yy);
2806 if (job->priv->header_format_right != NULL)
2807 print_header_footer_string (job, job->priv->header_format_right, 1.0, x, yy);
2810 if (job->priv->header_format_center != NULL)
2811 print_header_footer_string (job, job->priv->header_format_center, 0.5, x, yy);
2814 if (job->priv->header_separator)
2816 yy = y - (SEPARATOR_SPACING * (ascent + descent));
2817 gnome_print_setlinewidth (job->priv->print_ctxt, SEPARATOR_LINE_WIDTH);
2818 gnome_print_moveto (job->priv->print_ctxt, x, yy);
2819 gnome_print_lineto (job->priv->print_ctxt, x + width, yy);
2820 gnome_print_stroke (job->priv->print_ctxt);
2825 default_print_footer (GtkSourcePrintJob *job,
2831 gdouble ascent, descent;
2833 width = job->priv->text_width + job->priv->numbers_width;
2835 get_font_ascent_descent (job, job->priv->header_footer_font, &ascent, &descent);
2837 yy = y - job->priv->footer_height + descent;
2840 if (job->priv->footer_format_left != NULL)
2841 print_header_footer_string (job, job->priv->footer_format_left, 0.0, x, yy);
2844 if (job->priv->footer_format_right != NULL)
2845 print_header_footer_string (job, job->priv->footer_format_right, 1.0, x, yy);
2848 if (job->priv->footer_format_center != NULL)
2849 print_header_footer_string (job, job->priv->footer_format_center, 0.5, x, yy);
2852 if (job->priv->footer_separator)
2854 yy = y - job->priv->footer_height +
2855 (SEPARATOR_SPACING * (ascent + descent));
2856 gnome_print_setlinewidth (job->priv->print_ctxt, SEPARATOR_LINE_WIDTH);
2857 gnome_print_moveto (job->priv->print_ctxt, x, yy);
2858 gnome_print_lineto (job->priv->print_ctxt, x + width, yy);
2859 gnome_print_stroke (job->priv->print_ctxt);
2864 * gtk_source_print_job_set_print_header:
2865 * @job: a #GtkSourcePrintJob.
2866 * @setting: %TRUE if you want the header to be printed.
2868 * Sets whether you want to print a header in each page. The default
2869 * header consists of three pieces of text and an optional line
2870 * separator, configurable with
2871 * gtk_source_print_job_set_header_format().
2873 * Note that by default the header format is unspecified, and if it's
2874 * empty it will not be printed, regardless of this setting.
2877 gtk_source_print_job_set_print_header (GtkSourcePrintJob *job,
2880 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2881 g_return_if_fail (!job->priv->printing);
2883 setting = (setting != FALSE);
2885 if (setting == job->priv->print_header)
2888 job->priv->print_header = setting;
2890 g_object_notify (G_OBJECT (job), "print_header");
2894 * gtk_source_print_job_get_print_header:
2895 * @job: a #GtkSourcePrintJob.
2897 * Determines if a header is set to be printed for each page. A
2898 * header will be printed if this function returns %TRUE
2899 * <emphasis>and</emphasis> some format strings have been specified
2900 * with gtk_source_print_job_set_header_format().
2902 * Return value: %TRUE if the header is set to be printed.
2905 gtk_source_print_job_get_print_header (GtkSourcePrintJob *job)
2907 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2909 return job->priv->print_header;
2913 * gtk_source_print_job_set_print_footer:
2914 * @job: a #GtkSourcePrintJob.
2915 * @setting: %TRUE if you want the footer to be printed.
2917 * Sets whether you want to print a footer in each page. The default
2918 * footer consists of three pieces of text and an optional line
2919 * separator, configurable with
2920 * gtk_source_print_job_set_footer_format().
2922 * Note that by default the footer format is unspecified, and if it's
2923 * empty it will not be printed, regardless of this setting.
2926 gtk_source_print_job_set_print_footer (GtkSourcePrintJob *job,
2929 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2930 g_return_if_fail (!job->priv->printing);
2932 setting = (setting != FALSE);
2934 if (setting == job->priv->print_footer)
2937 job->priv->print_footer = setting;
2939 g_object_notify (G_OBJECT (job), "print_footer");
2943 * gtk_source_print_job_get_print_footer:
2944 * @job: a #GtkSourcePrintJob.
2946 * Determines if a footer is set to be printed for each page. A
2947 * footer will be printed if this function returns %TRUE
2948 * <emphasis>and</emphasis> some format strings have been specified
2949 * with gtk_source_print_job_set_footer_format().
2951 * Return value: %TRUE if the footer is set to be printed.
2954 gtk_source_print_job_get_print_footer (GtkSourcePrintJob *job)
2956 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), FALSE);
2958 return job->priv->print_footer;
2962 * gtk_source_print_job_set_header_footer_font_desc:
2963 * @job: a #GtkSourcePrintJob.
2964 * @desc: the #PangoFontDescription for the font to be used in headers and footers, or %NULL.
2966 * Sets the font for printing headers and footers. If %NULL is
2967 * supplied, the default font (i.e. the one being used for the text)
2968 * will be used instead.
2971 gtk_source_print_job_set_header_footer_font_desc (GtkSourcePrintJob *job,
2972 PangoFontDescription *desc)
2974 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
2975 g_return_if_fail (!job->priv->printing);
2978 desc = pango_font_description_copy (desc);
2979 if (job->priv->header_footer_font != NULL)
2980 pango_font_description_free (job->priv->header_footer_font);
2981 job->priv->header_footer_font = desc;
2982 g_object_freeze_notify (G_OBJECT (job));
2983 g_object_notify (G_OBJECT (job), "header_footer_font");
2984 g_object_notify (G_OBJECT (job), "header_footer_font_desc");
2985 g_object_thaw_notify (G_OBJECT (job));
2989 * gtk_source_print_job_set_header_footer_font:
2990 * @job: a #GtkSourcePrintJob.
2991 * @font_name: the full name of the font to be used in headers and footers, or %NULL.
2993 * Sets the font for printing headers and footers. If %NULL is
2994 * supplied, the default font (i.e. the one being used for the text)
2995 * will be used instead.
2997 * Note that @font_name is a #GnomeFont name not a Pango font
2998 * description string. This function is deprecated since #GnomeFont is
2999 * no longer used when implementing printing for GtkSourceView; you
3000 * should use gtk_source_print_job_set_header_footer_font_desc() instead.
3003 gtk_source_print_job_set_header_footer_font (GtkSourcePrintJob *job,
3004 const gchar *font_name)
3006 PangoFontDescription *desc;
3008 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3009 g_return_if_fail (!job->priv->printing);
3011 if (font_name != NULL)
3013 desc = font_description_from_gnome_font_name (font_name);
3016 gtk_source_print_job_set_header_footer_font_desc (job, desc);
3017 pango_font_description_free (desc);
3021 gtk_source_print_job_set_header_footer_font_desc (job, NULL);
3025 * gtk_source_print_job_get_header_footer_font_desc:
3026 * @job: a #GtkSourcePrintJob.
3028 * Determines the font to be used for the header and footer. This function
3029 * might return %NULL if a specific font has not been set.
3031 * Return value: the header and footer font description or %NULL. This value is
3032 * owned by the job and must not be modified or freed.
3034 PangoFontDescription *
3035 gtk_source_print_job_get_header_footer_font_desc (GtkSourcePrintJob *job)
3037 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
3039 return job->priv->header_footer_font;
3043 * gtk_source_print_job_get_header_footer_font:
3044 * @job: a #GtkSourcePrintJob.
3046 * Determines the font to be used for the header and footer. The
3047 * returned string is of the form "Fontfamily Style Size",
3048 * for example "Monospace Regular 10.0". The returned value
3049 * should be freed when no longer needed. This function might return
3050 * %NULL if a specific font has not been set.
3052 * Note that the result is a #GnomeFont name not a Pango font
3053 * description string. This function is deprecated since #GnomeFont is
3054 * no longer used when implementing printing for GtkSourceView; you
3055 * should use gtk_source_print_job_get_header_footer_font_desc() instead.
3057 * Return value: a newly allocated string with the name of the current
3058 * header and footer font, or %NULL.
3061 gtk_source_print_job_get_header_footer_font (GtkSourcePrintJob *job)
3063 g_return_val_if_fail (GTK_IS_SOURCE_PRINT_JOB (job), NULL);
3065 if (job->priv->header_footer_font != NULL)
3066 return font_description_to_gnome_font_name (job->priv->header_footer_font);
3072 * gtk_source_print_job_set_header_format:
3073 * @job: a #GtkSourcePrintJob.
3074 * @left: a format string to print on the left of the header.
3075 * @center: a format string to print on the center of the header.
3076 * @right: a format string to print on the right of the header.
3077 * @separator: %TRUE if you want a separator line to be printed.
3079 * Sets strftime like header format strings, to be printed on the
3080 * left, center and right of the top of each page. The strings may
3081 * include strftime(3) codes which will be expanded at print time.
3082 * All strftime() codes are accepted, with the addition of %N for the
3083 * page number and %Q for the page count.
3085 * @separator specifies if a solid line should be drawn to separate
3086 * the header from the document text.
3088 * If %NULL is given for any of the three arguments, that particular
3089 * string will not be printed. For the header to be printed, in
3090 * addition to specifying format strings, you need to enable header
3091 * printing with gtk_source_print_job_set_print_header().
3094 gtk_source_print_job_set_header_format (GtkSourcePrintJob *job,
3096 const gchar *center,
3100 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3101 g_return_if_fail (!job->priv->printing);
3103 /* FIXME: validate given strings? */
3104 g_free (job->priv->header_format_left);
3105 g_free (job->priv->header_format_center);
3106 g_free (job->priv->header_format_right);
3107 job->priv->header_format_left = g_strdup (left);
3108 job->priv->header_format_center = g_strdup (center);
3109 job->priv->header_format_right = g_strdup (right);
3110 job->priv->header_separator = separator;
3114 * gtk_source_print_job_set_footer_format:
3115 * @job: a #GtkSourcePrintJob.
3116 * @left: a format string to print on the left of the footer.
3117 * @center: a format string to print on the center of the footer.
3118 * @right: a format string to print on the right of the footer.
3119 * @separator: %TRUE if you want a separator line to be printed.
3121 * Like gtk_source_print_job_set_header_format(), but for the footer.
3124 gtk_source_print_job_set_footer_format (GtkSourcePrintJob *job,
3126 const gchar *center,
3130 g_return_if_fail (GTK_IS_SOURCE_PRINT_JOB (job));
3131 g_return_if_fail (!job->priv->printing);
3133 /* FIXME: validate given strings? */
3134 g_free (job->priv->footer_format_left);
3135 g_free (job->priv->footer_format_center);
3136 g_free (job->priv->footer_format_right);
3137 job->priv->footer_format_left = g_strdup (left);
3138 job->priv->footer_format_center = g_strdup (center);
3139 job->priv->footer_format_right = g_strdup (right);
3140 job->priv->footer_separator = separator;