1 #define __SP_GNOME_C__
3 /*
4 * Gnome stuff
5 *
6 * Author:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * Ted Gould <ted@gould.cx>
9 *
10 *
11 * Copyright (C) 2005 Authors
12 *
13 * Lauris: This code is in public domain
14 * Ted: This code is under the GNU GPL
15 */
17 /* Gnome Print */
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
23 #include <string.h>
25 #include "libnr/n-art-bpath.h"
26 #include "libnr/nr-rect.h"
27 #include "libnr/nr-matrix.h"
28 #include "libnr/nr-matrix-fns.h"
29 #include "libnr/nr-path.h"
30 #include "libnr/nr-pixblock.h"
31 #include "display/canvas-bpath.h"
33 #include <glib.h>
34 #include <gtk/gtkdialog.h>
35 #include <gtk/gtkbox.h>
36 #include <gtk/gtkstock.h>
38 #if OLDGnome
39 #include <libgnomeprint/gnome-print-master.h>
40 #include <libgnomeprintui/gnome-print-master-preview.h>
41 #endif
43 #include <glibmm/i18n.h>
44 #include "enums.h"
45 #include "document.h"
46 #include "style.h"
47 #include "sp-paint-server.h"
49 #include "gnome.h"
51 #include "extension/extension.h"
52 #include "extension/system.h"
54 static ArtBpath *nr_artpath_to_art_bpath(NArtBpath const *s);
56 namespace Inkscape {
57 namespace Extension {
58 namespace Internal {
60 PrintGNOME::PrintGNOME (void)
61 {
62 /* Nothing here */
63 }
65 PrintGNOME::~PrintGNOME (void)
66 {
67 return;
68 }
70 unsigned int
71 PrintGNOME::setup (Inkscape::Extension::Print *mod)
72 {
73 GnomePrintConfig *config;
74 #if OLDGnome
75 GtkWidget *dlg, *vbox, *sel;
76 #endif
78 config = gnome_print_config_default ();
79 #if OLDGnome
80 dlg = gtk_dialog_new_with_buttons (_("Select printer"), NULL,
81 GTK_DIALOG_MODAL,
82 GTK_STOCK_PRINT,
83 GTK_RESPONSE_OK,
84 GTK_STOCK_CANCEL,
85 GTK_RESPONSE_CANCEL,
86 NULL);
88 vbox = GTK_DIALOG (dlg)->vbox;
89 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
91 sel = gnome_printer_selector_new (config);
92 gtk_widget_show (sel);
93 gtk_box_pack_start (GTK_BOX (vbox), sel, TRUE, TRUE, 0);
95 btn = gtk_dialog_run (GTK_DIALOG (dlg));
96 gtk_widget_destroy (dlg);
97 if (btn != GTK_RESPONSE_OK) return FALSE;
98 #endif
99 _gpc = gnome_print_context_new (config);
100 gnome_print_config_unref (config);
102 return TRUE;
103 }
105 unsigned int
106 PrintGNOME::set_preview (Inkscape::Extension::Print *mod)
107 {
108 #if OLDGnome
109 SPPrintContext ctx;
110 GnomePrintContext *gpc;
111 GnomePrintMaster *gpm;
112 GtkWidget *gpmp;
113 gchar *title;
116 gpm = gnome_print_master_new();
117 _gpc = gnome_print_master_get_context (gpm);
119 g_return_if_fail (gpm != NULL);
120 g_return_if_fail (gpc != NULL);
122 /* Print document */
123 gnome_print_beginpage (gpc, SP_DOCUMENT_NAME (doc));
124 gnome_print_translate (gpc, 0.0, sp_document_height (doc));
125 /* From desktop points to document pixels */
126 gnome_print_scale (gpc, 0.8, -0.8);
127 sp_item_invoke_print (SP_ITEM (sp_document_root (doc)), &ctx);
128 gnome_print_showpage (gpc);
129 gnome_print_context_close (gpc);
131 title = g_strdup_printf (_("Inkscape: Print Preview"));
132 gpmp = gnome_print_master_preview_new (gpm, title);
134 gtk_widget_show (GTK_WIDGET(gpmp));
136 gnome_print_master_close (gpm);
138 g_free (title);
139 #endif
140 return 0;
141 }
143 unsigned int
144 PrintGNOME::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
145 {
146 gnome_print_beginpage (_gpc, (const guchar *)SP_DOCUMENT_NAME (doc));
147 gnome_print_translate (_gpc, 0.0, sp_document_height (doc));
148 /* From desktop points to document pixels */
149 gnome_print_scale (_gpc, 0.8, -0.8);
151 return 0;
152 }
154 unsigned int
155 PrintGNOME::finish (Inkscape::Extension::Print *mod)
156 {
157 gnome_print_showpage (_gpc);
158 gnome_print_context_close (_gpc);
160 return 0;
161 }
163 unsigned int
164 PrintGNOME::bind (Inkscape::Extension::Print *mod, const NRMatrix *transform, float opacity)
165 {
166 gdouble t[6];
168 gnome_print_gsave(_gpc);
170 t[0] = transform->c[0];
171 t[1] = transform->c[1];
172 t[2] = transform->c[2];
173 t[3] = transform->c[3];
174 t[4] = transform->c[4];
175 t[5] = transform->c[5];
177 gnome_print_concat (_gpc, t);
179 /* fixme: Opacity? (lauris) */
181 return 0;
182 }
184 unsigned int
185 PrintGNOME::release (Inkscape::Extension::Print *mod)
186 {
187 gnome_print_grestore (_gpc);
188 return 0;
189 }
191 unsigned int PrintGNOME::comment (Inkscape::Extension::Print * module,
192 const char * comment)
193 {
194 // ignore comment
195 return 0;
196 }
198 unsigned int
199 PrintGNOME::fill(Inkscape::Extension::Print *mod,
200 NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
201 NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
202 {
203 gdouble t[6];
205 /* CTM is for information purposes only */
206 /* We expect user coordinate system to be set up already */
208 t[0] = ctm->c[0];
209 t[1] = ctm->c[1];
210 t[2] = ctm->c[2];
211 t[3] = ctm->c[3];
212 t[4] = ctm->c[4];
213 t[5] = ctm->c[5];
215 if (style->fill.type == SP_PAINT_TYPE_COLOR) {
216 float rgb[3], opacity;
217 sp_color_get_rgb_floatv (&style->fill.value.color, rgb);
218 gnome_print_setrgbcolor (_gpc, rgb[0], rgb[1], rgb[2]);
220 /* fixme: */
221 opacity = SP_SCALE24_TO_FLOAT (style->fill_opacity.value) * SP_SCALE24_TO_FLOAT (style->opacity.value);
222 gnome_print_setopacity (_gpc, opacity);
224 ArtBpath * apath = nr_artpath_to_art_bpath(bpath->path);
225 gnome_print_bpath (_gpc, apath, FALSE);
226 g_free(apath);
228 if (style->fill_rule.value == SP_WIND_RULE_EVENODD) {
229 gnome_print_eofill (_gpc);
230 } else {
231 gnome_print_fill (_gpc);
232 }
233 } else if (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) {
234 SPPainter *painter;
235 NRRect dpbox;
237 /* fixme: */
238 dpbox.x0 = pbox->x0;
239 dpbox.y0 = pbox->y0;
240 dpbox.x1 = pbox->x1;
241 dpbox.y1 = pbox->y1;
242 painter = sp_paint_server_painter_new(SP_STYLE_FILL_SERVER(style),
243 // FIXME: the second matrix below must be the parent (context) transform.
244 // I don't know what it must be for gnome-print. --bb
245 ctm, NR::identity(),
246 &dpbox);
247 if (painter) {
248 NRRect cbox;
249 NRRectL ibox;
250 NRMatrix d2i;
251 double dd2i[6];
252 int x, y;
254 nr_rect_d_intersect (&cbox, dbox, bbox);
255 ibox.x0 = (long) cbox.x0;
256 ibox.y0 = (long) cbox.y0;
257 ibox.x1 = (long) (cbox.x1 + 0.9999);
258 ibox.y1 = (long) (cbox.y1 + 0.9999);
260 nr_matrix_invert (&d2i, ctm);
262 gnome_print_gsave (_gpc);
264 ArtBpath * apath = nr_artpath_to_art_bpath(bpath->path);
265 gnome_print_bpath (_gpc, apath, FALSE);
266 g_free(apath);
268 if (style->fill_rule.value == SP_WIND_RULE_EVENODD) {
269 gnome_print_eoclip (_gpc);
270 } else {
271 gnome_print_clip (_gpc);
272 }
273 dd2i[0] = d2i.c[0];
274 dd2i[1] = d2i.c[1];
275 dd2i[2] = d2i.c[2];
276 dd2i[3] = d2i.c[3];
277 dd2i[4] = d2i.c[4];
278 dd2i[5] = d2i.c[5];
279 gnome_print_concat (_gpc, dd2i);
280 /* Now we are in desktop coordinates */
281 for (y = ibox.y0; y < ibox.y1; y+= 64) {
282 for (x = ibox.x0; x < ibox.x1; x+= 64) {
283 NRPixBlock pb;
284 nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, x, y, x + 64, y + 64, TRUE);
285 painter->fill (painter, &pb);
286 gnome_print_gsave (_gpc);
287 gnome_print_translate (_gpc, x, y + 64);
288 gnome_print_scale (_gpc, 64, -64);
289 gnome_print_rgbaimage (_gpc, NR_PIXBLOCK_PX (&pb), 64, 64, pb.rs);
290 gnome_print_grestore (_gpc);
291 nr_pixblock_release (&pb);
292 }
293 }
294 gnome_print_grestore (_gpc);
295 sp_painter_free (painter);
296 }
297 }
299 return 0;
300 }
302 unsigned int
303 PrintGNOME::stroke (Inkscape::Extension::Print *mod, const NRBPath *bpath, const NRMatrix *ctm, const SPStyle *style,
304 const NRRect *pbox, const NRRect *dbox, const NRRect *bbox)
305 {
306 gdouble t[6];
308 /* CTM is for information purposes only */
309 /* We expect user coordinate system to be set up already */
311 t[0] = ctm->c[0];
312 t[1] = ctm->c[1];
313 t[2] = ctm->c[2];
314 t[3] = ctm->c[3];
315 t[4] = ctm->c[4];
316 t[5] = ctm->c[5];
318 if (style->stroke.type == SP_PAINT_TYPE_COLOR) {
319 float rgb[3], opacity;
320 sp_color_get_rgb_floatv (&style->stroke.value.color, rgb);
321 gnome_print_setrgbcolor (_gpc, rgb[0], rgb[1], rgb[2]);
323 /* fixme: */
324 opacity = SP_SCALE24_TO_FLOAT (style->stroke_opacity.value) * SP_SCALE24_TO_FLOAT (style->opacity.value);
325 gnome_print_setopacity (_gpc, opacity);
327 if (style->stroke_dash.n_dash > 0) {
328 gnome_print_setdash (_gpc, style->stroke_dash.n_dash, style->stroke_dash.dash, style->stroke_dash.offset);
329 } else {
330 gnome_print_setdash (_gpc, 0, NULL, 0.0);
331 }
333 gnome_print_setlinewidth (_gpc, style->stroke_width.computed);
334 gnome_print_setlinejoin (_gpc, style->stroke_linejoin.computed);
335 gnome_print_setlinecap (_gpc, style->stroke_linecap.computed);
337 ArtBpath * apath = nr_artpath_to_art_bpath(bpath->path);
338 gnome_print_bpath (_gpc, apath, FALSE);
339 g_free(apath);
341 gnome_print_stroke (_gpc);
342 }
344 return 0;
345 }
347 unsigned int
348 PrintGNOME::image (Inkscape::Extension::Print *mod, unsigned char *px, unsigned int w, unsigned int h, unsigned int rs,
349 const NRMatrix *transform, const SPStyle *style)
350 {
351 gdouble t[6];
353 t[0] = transform->c[0];
354 t[1] = transform->c[1];
355 t[2] = transform->c[2];
356 t[3] = transform->c[3];
357 t[4] = transform->c[4];
358 t[5] = transform->c[5];
360 gnome_print_gsave (_gpc);
362 gnome_print_concat (_gpc, t);
364 if (style->opacity.value != SP_SCALE24_MAX) {
365 guchar *dpx, *d, *s;
366 guint x, y;
367 guint32 alpha;
368 alpha = (guint32) floor (SP_SCALE24_TO_FLOAT (style->opacity.value) * 255.9999);
369 dpx = g_new (guchar, w * h * 4);
370 for (y = 0; y < h; y++) {
371 s = px + y * rs;
372 d = dpx + y * w * 4;
373 memcpy (d, s, w * 4);
374 for (x = 0; x < w; x++) {
375 d[3] = (s[3] * alpha) / 255;
376 s += 4;
377 d += 4;
378 }
379 }
380 gnome_print_rgbaimage (_gpc, dpx, w, h, w * 4);
381 g_free (dpx);
382 } else {
383 gnome_print_rgbaimage (_gpc, px, w, h, rs);
384 }
386 gnome_print_grestore (_gpc);
388 return 0;
389 }
391 #include "clear-n_.h"
393 void
394 PrintGNOME::init (void)
395 {
396 Inkscape::Extension::Extension * ext;
398 /* SVG in */
399 ext = Inkscape::Extension::build_from_mem(
400 "<inkscape-extension>\n"
401 "<name>" N_("GNOME Print") "</name>\n"
402 "<id>" SP_MODULE_KEY_PRINT_GNOME "</id>\n"
403 "<print/>\n"
404 "</inkscape-extension>", new PrintGNOME());
406 return;
407 }
409 } /* namespace Internal */
410 } /* namespace Extension */
411 } /* namespace Inkscape */
414 // Remember to free the result!
415 static ArtBpath *
416 nr_artpath_to_art_bpath(NArtBpath const *s)
417 {
418 int i;
419 if (!s) {
420 return NULL;
421 }
423 i = 0;
424 while (s[i].code != NR_END) i += 1;
426 ArtBpath* d = g_new (ArtBpath, i + 1);
428 i = 0;
429 while (s[i].code != NR_END) {
430 d[i].code = (ArtPathcode)s[i].code;
431 if (s[i].code == NR_CURVETO) {
432 d[i].x1 = s[i].x1;
433 d[i].y1 = s[i].y1;
434 d[i].x2 = s[i].x2;
435 d[i].y2 = s[i].y2;
436 }
437 d[i].x3 = s[i].x3;
438 d[i].y3 = s[i].y3;
439 i += 1;
440 }
441 d[i].code = ART_END;
443 return d;
444 }