Code

fe395851eab63239802c420a8172327c7b461830
[inkscape.git] / src / print.cpp
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 # include <unistd.h>   // close, unlink
29 # include <cstdio>
30 using std::fprintf;
31 #endif
33 #if 0
34 # include <extension/internal/ps.h>
36 # ifdef WIN32
37 #  include <extension/internal/win32.h>
38 # endif
40 # ifdef WITH_GNOME_PRINT
41 #  include <extension/internal/gnome.h>
42 # endif
43 #endif
45 /* Identity typedef */
47 unsigned int sp_print_bind(SPPrintContext *ctx, NR::Matrix const &transform, float opacity)
48 {
49     NRMatrix const ntransform(transform);
50     return sp_print_bind(ctx, &ntransform, opacity);
51 }
53 unsigned int
54 sp_print_bind(SPPrintContext *ctx, NRMatrix const *transform, float opacity)
55 {
56     return ctx->module->bind(transform, opacity);
57 }
59 unsigned int
60 sp_print_release(SPPrintContext *ctx)
61 {
62     return ctx->module->release();
63 }
65 unsigned int
66 sp_print_comment(SPPrintContext *ctx, char const *comment)
67 {
68     return ctx->module->comment(comment);
69 }
71 unsigned int
72 sp_print_fill(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
73               NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
74 {
75     return ctx->module->fill(bpath, ctm, style, pbox, dbox, bbox);
76 }
78 unsigned int
79 sp_print_stroke(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
80                 NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
81 {
82     return ctx->module->stroke(bpath, ctm, style, pbox, dbox, bbox);
83 }
85 unsigned int
86 sp_print_image_R8G8B8A8_N(SPPrintContext *ctx,
87                           guchar *px, unsigned int w, unsigned int h, unsigned int rs,
88                           NRMatrix const *transform, SPStyle const *style)
89 {
90     return ctx->module->image(px, w, h, rs, transform, style);
91 }
93 unsigned int sp_print_text(SPPrintContext *ctx, char const *text, NR::Point p,
94                            SPStyle const *style)
95 {
96     return ctx->module->text(text, p, style);
97 }
99 #include "display/nr-arena.h"
100 #include "display/nr-arena-item.h"
102 /* UI */
104 void
105 sp_print_preview_document(SPDocument *doc)
107     Inkscape::Extension::Print *mod;
108     unsigned int ret;
110     sp_document_ensure_up_to_date(doc);
112     mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
114     ret = mod->set_preview();
116     if (ret) {
117         SPPrintContext context;
118         context.module = mod;
120         /* fixme: This has to go into module constructor somehow */
121         /* Create new arena */
122         mod->base = SP_ITEM(sp_document_root(doc));
123         mod->arena = NRArena::create();
124         mod->dkey = sp_item_display_key_new(1);
125         mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
126         /* Print document */
127         ret = mod->begin(doc);
128         sp_item_invoke_print(mod->base, &context);
129         ret = mod->finish();
130         /* Release arena */
131         sp_item_invoke_hide(mod->base, mod->dkey);
132         mod->base = NULL;
133         nr_arena_item_unref(mod->root);
134         mod->root = NULL;
135         nr_object_unref((NRObject *) mod->arena);
136         mod->arena = NULL;
137     }
139     return;
142 #ifdef HAVE_GTK_UNIX_PRINT
143 static void
144 unix_print_complete (GtkPrintJob *print_job,
145                      gpointer user_data,
146                      GError *error)
148     fprintf(stderr,"print job finished: %s\n",error ? error->message : "no error");
151 static void
152 unix_print_dialog (const gchar * ps_file, const gchar * jobname)
154     Glib::ustring title = _("Print");
155     title += " ";
156     title += jobname;
157     GtkWidget* dlg = gtk_print_unix_dialog_new(title.c_str(), NULL);
159     // force output system to only handle our pre-generated PS output
160     gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG(dlg),
161                                                    GTK_PRINT_CAPABILITY_GENERATE_PS);
163 /*
164  * It would be nice to merge the PrintPS::setup routine with a custom
165  * configuration dialog:
166    
167     gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog,
168                                           GtkWidget *child,
169                                           GtkWidget *tab_label);
170 */
172     int const response = gtk_dialog_run(GTK_DIALOG(dlg));
174     if (response == GTK_RESPONSE_OK) {
175         GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dlg));
177         if (gtk_printer_accepts_ps (printer)) {
178             GtkPrintJob* job = gtk_print_job_new  (jobname, printer,
179               gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dlg)),
180               gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dlg)));
183             GError * error = NULL;
184             if ( gtk_print_job_set_source_file (job, ps_file, &error)) {
185                 gtk_print_job_send (job, unix_print_complete, NULL, NULL);
186             }
187             else {
188                 g_warning(_("Could not set print source: %s"),error ? error->message : _("unknown error"));
189             }
190             if (error) g_error_free(error);
191         }
192         else {
193             g_warning(_("Printer '%s' does not support PS output"), gtk_printer_get_name (printer));
194         }
195     }
196     else if (response == GTK_RESPONSE_APPLY) {
197         // since we didn't include the Preview capability,
198         // this should never happen.
199         g_warning(_("Print Preview not available"));
200     }
202     gtk_widget_destroy(dlg);
204 #endif // HAVE_GTK_UNIX_PRINT
207 void
208 sp_print_document(SPDocument *doc, unsigned int direct)
210     Inkscape::Extension::Print *mod;
211     unsigned int ret;
212 #ifdef HAVE_GTK_UNIX_PRINT
213     Glib::ustring tmpfile = "";
214 #endif
216     sp_document_ensure_up_to_date(doc);
218     if (direct) {
219         mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
220     } else {
221         mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
223 #ifdef HAVE_GTK_UNIX_PRINT
224         // unix print dialog reads from the exported tempfile
225         gchar  *filename = NULL;
226         GError *error    = NULL;
227         gint tmpfd = g_file_open_tmp("inkscape-ps-XXXXXX",
228                                      &filename,
229                                      &error);
230         if (tmpfd<0) {
231             g_warning(_("Failed to create tempfile for printing: %s"),
232                       error ? error->message : _("unknown error"));
233             if (error) g_error_free(error);
234             return;
235         }
236         tmpfile = filename;
237         g_free(filename);
238         close(tmpfd);
240         Glib::ustring destination = ">" + tmpfile;
241         mod->set_param_string("destination", destination.c_str());
242 #endif
243     }
245     ret = mod->setup();
247     if (ret) {
248         SPPrintContext context;
249         context.module = mod;
251         /* fixme: This has to go into module constructor somehow */
252         /* Create new arena */
253         mod->base = SP_ITEM(sp_document_root(doc));
254         mod->arena = NRArena::create();
255         mod->dkey = sp_item_display_key_new(1);
256         mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
257         /* Print document */
258         ret = mod->begin(doc);
259         sp_item_invoke_print(mod->base, &context);
260         ret = mod->finish();
261         /* Release arena */
262         sp_item_invoke_hide(mod->base, mod->dkey);
263         mod->base = NULL;
264         nr_arena_item_unref(mod->root);
265         mod->root = NULL;
266         nr_object_unref((NRObject *) mod->arena);
267         mod->arena = NULL;
269 #ifdef HAVE_GTK_UNIX_PRINT
270         // redirect output to new print dialog
271         unix_print_dialog(tmpfile.c_str(),doc->name ? doc->name : _("SVG Document"));
272         unlink(tmpfile.c_str());
273         // end redirected new print dialog
274 #endif
275     }
277     return;
280 void
281 sp_print_document_to_file(SPDocument *doc, gchar const *filename)
283     Inkscape::Extension::Print *mod;
284     SPPrintContext context;
285     gchar const *oldconst;
286     gchar *oldoutput;
287     unsigned int ret;
289     sp_document_ensure_up_to_date(doc);
291     mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
292     oldconst = mod->get_param_string("destination");
293     oldoutput = g_strdup(oldconst);
294     mod->set_param_string("destination", (gchar *)filename);
296 /* Start */
297     context.module = mod;
298     /* fixme: This has to go into module constructor somehow */
299     /* Create new arena */
300     mod->base = SP_ITEM(sp_document_root(doc));
301     mod->arena = NRArena::create();
302     mod->dkey = sp_item_display_key_new(1);
303     mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
304     /* Print document */
305     ret = mod->begin(doc);
306     sp_item_invoke_print(mod->base, &context);
307     ret = mod->finish();
308     /* Release arena */
309     sp_item_invoke_hide(mod->base, mod->dkey);
310     mod->base = NULL;
311     nr_arena_item_unref(mod->root);
312     mod->root = NULL;
313     nr_object_unref((NRObject *) mod->arena);
314     mod->arena = NULL;
315 /* end */
317     mod->set_param_string("destination", oldoutput);
318     g_free(oldoutput);
320     return;
324 /*
325   Local Variables:
326   mode:c++
327   c-file-style:"stroustrup"
328   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
329   indent-tabs-mode:nil
330   fill-column:99
331   End:
332 */
333 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :