1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | /* This file is part of the GtkHTML library. |
---|
3 | |
---|
4 | Copyright (C) 2000 Helix Code, Inc. |
---|
5 | |
---|
6 | This library is free software; you can redistribute it and/or |
---|
7 | modify it under the terms of the GNU Library General Public |
---|
8 | License as published by the Free Software Foundation; either |
---|
9 | version 2 of the License, or (at your option) any later version. |
---|
10 | |
---|
11 | This library is distributed in the hope that it will be useful, |
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
14 | Library General Public License for more details. |
---|
15 | |
---|
16 | You should have received a copy of the GNU Library General Public License |
---|
17 | along with this library; see the file COPYING.LIB. If not, write to |
---|
18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
19 | Boston, MA 02111-1307, USA. |
---|
20 | */ |
---|
21 | |
---|
22 | #include <config.h> |
---|
23 | #include <gtk/gtk.h> |
---|
24 | #include <libgnome/gnome-defs.h> |
---|
25 | #include <libgnome/gnome-i18n.h> |
---|
26 | #include <libgnomeui/gnome-dialog-util.h> |
---|
27 | #include "gtkhtml.h" |
---|
28 | #include "gtkhtml-private.h" |
---|
29 | #include "gtkhtml-properties.h" |
---|
30 | #include "htmlprinter.h" |
---|
31 | #include "htmlengine-print.h" |
---|
32 | #include "htmlobject.h" |
---|
33 | |
---|
34 | |
---|
35 | |
---|
36 | /* #define CLIP_DEBUG */ |
---|
37 | |
---|
38 | static void |
---|
39 | print_header_footer (HTMLPainter *painter, HTMLEngine *engine, gint width, gint y, gdouble height, |
---|
40 | GtkHTMLPrintCallback cb, gpointer user_data) |
---|
41 | { |
---|
42 | HTMLPrinter *printer = HTML_PRINTER (painter); |
---|
43 | GnomePrintContext *context = printer->print_context; |
---|
44 | gdouble gx, gy; |
---|
45 | |
---|
46 | gnome_print_gsave (context); |
---|
47 | html_painter_set_clip_rectangle (painter, 0, y, |
---|
48 | width, SCALE_GNOME_PRINT_TO_ENGINE (height)); |
---|
49 | #ifdef CLIP_DEBUG |
---|
50 | html_painter_draw_rect (painter, 0, y, |
---|
51 | SCALE_GNOME_PRINT_TO_ENGINE (width), SCALE_GNOME_PRINT_TO_ENGINE (height)); |
---|
52 | #endif |
---|
53 | html_printer_coordinates_to_gnome_print (printer, 0, y, &gx, &gy); |
---|
54 | (*cb) (GTK_HTML (engine->widget), context, gx, gy, SCALE_ENGINE_TO_GNOME_PRINT (width), height, user_data); |
---|
55 | gnome_print_grestore (context); |
---|
56 | } |
---|
57 | |
---|
58 | static void |
---|
59 | print_page (HTMLPainter *painter, |
---|
60 | HTMLEngine *engine, |
---|
61 | gint start_y, |
---|
62 | gint page_width, gint page_height, gint body_height, |
---|
63 | gdouble header_height, gdouble footer_height, |
---|
64 | GtkHTMLPrintCallback header_print, GtkHTMLPrintCallback footer_print, gpointer user_data) |
---|
65 | { |
---|
66 | HTMLPrinter *printer = HTML_PRINTER (painter); |
---|
67 | GnomePrintContext *context = printer->print_context; |
---|
68 | |
---|
69 | html_painter_begin (painter, 0, 0, page_width, page_height); |
---|
70 | if (header_print) |
---|
71 | print_header_footer (painter, engine, page_width, 0, header_height/printer->scale, header_print, user_data); |
---|
72 | gnome_print_gsave (context); |
---|
73 | html_painter_set_clip_rectangle (painter, 0, header_height, page_width, body_height); |
---|
74 | #ifdef CLIP_DEBUG |
---|
75 | html_painter_draw_rect (painter, 0, header_height, page_width, body_height); |
---|
76 | #endif |
---|
77 | html_object_draw (engine->clue, painter, |
---|
78 | 0, start_y, |
---|
79 | page_width, body_height, |
---|
80 | 0, -start_y + header_height / printer->scale); |
---|
81 | gnome_print_grestore (context); |
---|
82 | if (footer_print) |
---|
83 | print_header_footer (painter, engine, page_width*printer->scale, |
---|
84 | page_height - SCALE_GNOME_PRINT_TO_ENGINE (footer_height/printer->scale), |
---|
85 | footer_height/printer->scale, footer_print, user_data); |
---|
86 | html_painter_end (painter); |
---|
87 | } |
---|
88 | |
---|
89 | static gint |
---|
90 | print_all_pages (HTMLPainter *painter, |
---|
91 | HTMLEngine *engine, |
---|
92 | gdouble header_height, gdouble footer_height, |
---|
93 | GtkHTMLPrintCallback header_print, GtkHTMLPrintCallback footer_print, gpointer user_data, gboolean do_print) |
---|
94 | { |
---|
95 | HTMLPrinter *printer = HTML_PRINTER (painter); |
---|
96 | gint new_split_offset, split_offset; |
---|
97 | gint page_width, page_height, body_height; |
---|
98 | gint document_height; |
---|
99 | gint pages = 0; |
---|
100 | |
---|
101 | page_height = html_printer_get_page_height (printer); |
---|
102 | page_width = html_printer_get_page_width (printer); |
---|
103 | |
---|
104 | if (header_height + footer_height >= page_height*printer->scale) { |
---|
105 | header_print = footer_print = NULL; |
---|
106 | g_warning ("Page header height + footer height >= page height, disabling header/footer printing"); |
---|
107 | } |
---|
108 | |
---|
109 | body_height = page_height |
---|
110 | - SCALE_GNOME_PRINT_TO_ENGINE (header_height/printer->scale + footer_height/printer->scale); |
---|
111 | split_offset = 0; |
---|
112 | |
---|
113 | document_height = html_engine_get_doc_height (engine); |
---|
114 | |
---|
115 | do { |
---|
116 | pages ++; |
---|
117 | new_split_offset = html_object_check_page_split (engine->clue, |
---|
118 | split_offset + body_height); |
---|
119 | |
---|
120 | if (new_split_offset <= split_offset |
---|
121 | || new_split_offset - split_offset < engine->min_split_index * body_height) |
---|
122 | new_split_offset = split_offset + body_height; |
---|
123 | |
---|
124 | if (do_print) |
---|
125 | print_page (painter, engine, split_offset, |
---|
126 | page_width, page_height, |
---|
127 | new_split_offset - split_offset, |
---|
128 | header_height, footer_height, header_print, footer_print, user_data); |
---|
129 | |
---|
130 | split_offset = new_split_offset; |
---|
131 | } while (split_offset < document_height); |
---|
132 | |
---|
133 | return pages; |
---|
134 | } |
---|
135 | |
---|
136 | static gboolean |
---|
137 | do_we_have_default_font (HTMLPainter *painter) |
---|
138 | { |
---|
139 | HTMLFont *font; |
---|
140 | gboolean rv = FALSE; |
---|
141 | |
---|
142 | font = html_painter_get_font (painter, NULL, GTK_HTML_FONT_STYLE_DEFAULT); |
---|
143 | if (font) { |
---|
144 | rv = TRUE; |
---|
145 | } |
---|
146 | |
---|
147 | return rv; |
---|
148 | } |
---|
149 | |
---|
150 | static gint |
---|
151 | print_with_header_footer (HTMLEngine *engine, |
---|
152 | GnomePrintContext *print_context, |
---|
153 | gdouble header_height, |
---|
154 | gdouble footer_height, |
---|
155 | GtkHTMLPrintCallback header_print, |
---|
156 | GtkHTMLPrintCallback footer_print, |
---|
157 | gpointer user_data, gboolean do_print) |
---|
158 | { |
---|
159 | HTMLPainter *printer; |
---|
160 | HTMLPainter *old_painter; |
---|
161 | GtkHTMLClassProperties *prop = GTK_HTML_CLASS (GTK_OBJECT (engine->widget)->klass)->properties; |
---|
162 | gint pages = 0; |
---|
163 | |
---|
164 | g_return_val_if_fail (engine->clue != NULL, 0); |
---|
165 | |
---|
166 | printer = html_printer_new (print_context, GTK_HTML (engine->widget)->priv->print_master); |
---|
167 | html_font_manager_set_default (html_engine_font_manager_with_painter (engine, printer), |
---|
168 | prop->font_var_print, prop->font_fix_print, |
---|
169 | prop->font_var_size_print, prop->font_var_print_points, |
---|
170 | prop->font_fix_size_print, prop->font_fix_print_points); |
---|
171 | |
---|
172 | if (do_we_have_default_font (printer)) { |
---|
173 | gint min_width, page_width; |
---|
174 | |
---|
175 | old_painter = engine->painter; |
---|
176 | |
---|
177 | gtk_object_ref (GTK_OBJECT (old_painter)); |
---|
178 | html_engine_set_painter (engine, printer); |
---|
179 | |
---|
180 | min_width = html_engine_calc_min_width (engine); |
---|
181 | page_width = html_painter_get_page_width (engine->painter, engine); |
---|
182 | /* printf ("min_width %d page %d\n", min_width, page_width); */ |
---|
183 | if (min_width > page_width) { |
---|
184 | HTML_PRINTER (printer)->scale = MAX (0.5, ((gdouble) page_width) / min_width); |
---|
185 | html_object_change_set_down (engine->clue, HTML_CHANGE_ALL); |
---|
186 | html_engine_calc_size (engine, NULL); |
---|
187 | /* printf ("scale %lf\n", HTML_PRINTER (printer)->scale); |
---|
188 | gtk_html_debug_dump_tree (engine->clue, 0); */ |
---|
189 | } |
---|
190 | |
---|
191 | pages = print_all_pages (HTML_PAINTER (printer), engine, |
---|
192 | header_height, footer_height, |
---|
193 | header_print, footer_print, |
---|
194 | user_data, do_print); |
---|
195 | |
---|
196 | html_engine_set_painter (engine, old_painter); |
---|
197 | gtk_object_unref (GTK_OBJECT (old_painter)); |
---|
198 | } else { |
---|
199 | gnome_ok_dialog (_("Cannot allocate default font for printing\n")); |
---|
200 | } |
---|
201 | |
---|
202 | gtk_object_unref (GTK_OBJECT (printer)); |
---|
203 | |
---|
204 | return pages; |
---|
205 | } |
---|
206 | |
---|
207 | void |
---|
208 | html_engine_print (HTMLEngine *engine, GnomePrintContext *print_context) |
---|
209 | { |
---|
210 | html_engine_print_with_header_footer (engine, print_context, .0, .0, NULL, NULL, NULL); |
---|
211 | } |
---|
212 | |
---|
213 | void |
---|
214 | html_engine_print_with_header_footer (HTMLEngine *engine, |
---|
215 | GnomePrintContext *print_context, |
---|
216 | gdouble header_height, |
---|
217 | gdouble footer_height, |
---|
218 | GtkHTMLPrintCallback header_print, |
---|
219 | GtkHTMLPrintCallback footer_print, |
---|
220 | gpointer user_data) |
---|
221 | { |
---|
222 | print_with_header_footer (engine, print_context, |
---|
223 | header_height, footer_height, header_print, footer_print, user_data, TRUE); |
---|
224 | } |
---|
225 | |
---|
226 | gint |
---|
227 | html_engine_print_get_pages_num (HTMLEngine *e, GnomePrintContext *print_context, |
---|
228 | gdouble header_height, gdouble footer_height) |
---|
229 | { |
---|
230 | return print_with_header_footer (e, print_context, header_height, footer_height, NULL, NULL, NULL, FALSE); |
---|
231 | } |
---|
232 | |
---|
233 | void |
---|
234 | html_engine_print_set_min_split_index (HTMLEngine *e, gdouble idx) |
---|
235 | { |
---|
236 | e->min_split_index = idx; |
---|
237 | } |
---|