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