1 #define __SP_PRINT_C__
3 /** \file
4 * Frontend to printing
5 */
6 /*
7 * Author:
8 * Lauris Kaplinski <lauris@kaplinski.com>
9 *
10 * This code is in public domain
11 */
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
19 #include "sp-item.h"
20 #include "extension/print.h"
21 #include "extension/system.h"
22 #include "print.h"
24 #ifdef HAVE_GTK_UNIX_PRINT
25 #include <gtk/gtk.h>
26 #include <glibmm/i18n.h>
27 #include <gtk/gtkprintunixdialog.h>
28 #endif
30 #ifdef SOLARIS_2_8
31 #include <unistd.h>
32 #endif
34 #if 0
35 # include <extension/internal/ps.h>
37 # ifdef WIN32
38 # include <extension/internal/win32.h>
39 # endif
41 # ifdef WITH_GNOME_PRINT
42 # include <extension/internal/gnome.h>
43 # endif
44 #endif
46 /* Identity typedef */
48 unsigned int sp_print_bind(SPPrintContext *ctx, NR::Matrix const &transform, float opacity)
49 {
50 NRMatrix const ntransform(transform);
51 return sp_print_bind(ctx, &ntransform, opacity);
52 }
54 unsigned int
55 sp_print_bind(SPPrintContext *ctx, NRMatrix const *transform, float opacity)
56 {
57 return ctx->module->bind(transform, opacity);
58 }
60 unsigned int
61 sp_print_release(SPPrintContext *ctx)
62 {
63 return ctx->module->release();
64 }
66 unsigned int
67 sp_print_comment(SPPrintContext *ctx, char const *comment)
68 {
69 return ctx->module->comment(comment);
70 }
72 unsigned int
73 sp_print_fill(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
74 NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
75 {
76 return ctx->module->fill(bpath, ctm, style, pbox, dbox, bbox);
77 }
79 unsigned int
80 sp_print_stroke(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
81 NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
82 {
83 return ctx->module->stroke(bpath, ctm, style, pbox, dbox, bbox);
84 }
86 unsigned int
87 sp_print_image_R8G8B8A8_N(SPPrintContext *ctx,
88 guchar *px, unsigned int w, unsigned int h, unsigned int rs,
89 NRMatrix const *transform, SPStyle const *style)
90 {
91 return ctx->module->image(px, w, h, rs, transform, style);
92 }
94 unsigned int sp_print_text(SPPrintContext *ctx, char const *text, NR::Point p,
95 SPStyle const *style)
96 {
97 return ctx->module->text(text, p, style);
98 }
100 #include "display/nr-arena.h"
101 #include "display/nr-arena-item.h"
103 /* UI */
105 void
106 sp_print_preview_document(SPDocument *doc)
107 {
108 Inkscape::Extension::Print *mod;
109 unsigned int ret;
111 sp_document_ensure_up_to_date(doc);
113 mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
115 ret = mod->set_preview();
117 if (ret) {
118 SPPrintContext context;
119 context.module = mod;
121 /* fixme: This has to go into module constructor somehow */
122 /* Create new arena */
123 mod->base = SP_ITEM(sp_document_root(doc));
124 mod->arena = NRArena::create();
125 mod->dkey = sp_item_display_key_new(1);
126 mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
127 /* Print document */
128 ret = mod->begin(doc);
129 sp_item_invoke_print(mod->base, &context);
130 ret = mod->finish();
131 /* Release arena */
132 sp_item_invoke_hide(mod->base, mod->dkey);
133 mod->base = NULL;
134 nr_arena_item_unref(mod->root);
135 mod->root = NULL;
136 nr_object_unref((NRObject *) mod->arena);
137 mod->arena = NULL;
138 }
140 return;
141 }
143 #ifdef HAVE_GTK_UNIX_PRINT
144 static void
145 unix_print_complete (GtkPrintJob *print_job,
146 gpointer user_data,
147 GError *error)
148 {
149 fprintf(stderr,"print job finished: %s\n",error ? error->message : "no error");
150 }
152 static void
153 unix_print_dialog (const gchar * ps_file, const gchar * jobname)
154 {
155 Glib::ustring title = _("Print");
156 title += " ";
157 title += jobname;
158 GtkWidget* dlg = gtk_print_unix_dialog_new(title.c_str(), NULL);
160 // force output system to only handle our pre-generated PS output
161 gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG(dlg),
162 GTK_PRINT_CAPABILITY_GENERATE_PS);
164 /*
165 * It would be nice to merge the PrintPS::setup routine with a custom
166 * configuration dialog:
168 gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog,
169 GtkWidget *child,
170 GtkWidget *tab_label);
171 */
173 int const response = gtk_dialog_run(GTK_DIALOG(dlg));
175 if (response == GTK_RESPONSE_OK) {
176 GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dlg));
178 if (gtk_printer_accepts_ps (printer)) {
179 GtkPrintJob* job = gtk_print_job_new (jobname, printer,
180 gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dlg)),
181 gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dlg)));
184 GError * error = NULL;
185 if ( gtk_print_job_set_source_file (job, ps_file, &error)) {
186 gtk_print_job_send (job, unix_print_complete, NULL, NULL);
187 }
188 else {
189 g_warning(_("Could not set print source: %s"),error ? error->message : _("unknown error"));
190 }
191 if (error) g_error_free(error);
192 }
193 else {
194 g_warning(_("Printer '%s' does not support PS output"), gtk_printer_get_name (printer));
195 }
196 }
197 else if (response == GTK_RESPONSE_APPLY) {
198 // since we didn't include the Preview capability,
199 // this should never happen.
200 g_warning(_("Print Preview not available"));
201 }
203 gtk_widget_destroy(dlg);
204 }
205 #endif // HAVE_GTK_UNIX_PRINT
208 void
209 sp_print_document(SPDocument *doc, unsigned int direct)
210 {
211 Inkscape::Extension::Print *mod;
212 unsigned int ret;
213 #ifdef HAVE_GTK_UNIX_PRINT
214 Glib::ustring tmpfile = "";
215 #endif
217 sp_document_ensure_up_to_date(doc);
219 if (direct) {
220 mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
221 } else {
222 mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
224 #ifdef HAVE_GTK_UNIX_PRINT
225 // unix print dialog reads from the exported tempfile
226 gchar *filename = NULL;
227 GError *error = NULL;
228 gint tmpfd = g_file_open_tmp("inkscape-ps-XXXXXX",
229 &filename,
230 &error);
231 if (tmpfd<0) {
232 g_warning(_("Failed to create tempfile for printing: %s"),
233 error ? error->message : _("unknown error"));
234 if (error) g_error_free(error);
235 return;
236 }
237 tmpfile = filename;
238 g_free(filename);
239 close(tmpfd);
241 Glib::ustring destination = ">" + tmpfile;
242 mod->set_param_string("destination", destination.c_str());
243 #endif
244 }
246 ret = mod->setup();
248 if (ret) {
249 SPPrintContext context;
250 context.module = mod;
252 /* fixme: This has to go into module constructor somehow */
253 /* Create new arena */
254 mod->base = SP_ITEM(sp_document_root(doc));
255 mod->arena = NRArena::create();
256 mod->dkey = sp_item_display_key_new(1);
257 mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
258 /* Print document */
259 ret = mod->begin(doc);
260 sp_item_invoke_print(mod->base, &context);
261 ret = mod->finish();
262 /* Release arena */
263 sp_item_invoke_hide(mod->base, mod->dkey);
264 mod->base = NULL;
265 nr_arena_item_unref(mod->root);
266 mod->root = NULL;
267 nr_object_unref((NRObject *) mod->arena);
268 mod->arena = NULL;
270 #ifdef HAVE_GTK_UNIX_PRINT
271 // redirect output to new print dialog
272 unix_print_dialog(tmpfile.c_str(),doc->name ? doc->name : _("SVG Document"));
273 unlink(tmpfile.c_str());
274 // end redirected new print dialog
275 #endif
276 }
278 return;
279 }
281 void
282 sp_print_document_to_file(SPDocument *doc, gchar const *filename)
283 {
284 Inkscape::Extension::Print *mod;
285 SPPrintContext context;
286 gchar const *oldconst;
287 gchar *oldoutput;
288 unsigned int ret;
290 sp_document_ensure_up_to_date(doc);
292 mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
293 oldconst = mod->get_param_string("destination");
294 oldoutput = g_strdup(oldconst);
295 mod->set_param_string("destination", (gchar *)filename);
297 /* Start */
298 context.module = mod;
299 /* fixme: This has to go into module constructor somehow */
300 /* Create new arena */
301 mod->base = SP_ITEM(sp_document_root(doc));
302 mod->arena = NRArena::create();
303 mod->dkey = sp_item_display_key_new(1);
304 mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
305 /* Print document */
306 ret = mod->begin(doc);
307 sp_item_invoke_print(mod->base, &context);
308 ret = mod->finish();
309 /* Release arena */
310 sp_item_invoke_hide(mod->base, mod->dkey);
311 mod->base = NULL;
312 nr_arena_item_unref(mod->root);
313 mod->root = NULL;
314 nr_object_unref((NRObject *) mod->arena);
315 mod->arena = NULL;
316 /* end */
318 mod->set_param_string("destination", oldoutput);
319 g_free(oldoutput);
321 return;
322 }
325 /*
326 Local Variables:
327 mode:c++
328 c-file-style:"stroustrup"
329 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
330 indent-tabs-mode:nil
331 fill-column:99
332 End:
333 */
334 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :