#define __SP_GNOME_C__ /* * Gnome stuff * * Author: * Lauris Kaplinski * Ted Gould * * * Copyright (C) 2005 Authors * * Lauris: This code is in public domain * Ted: This code is under the GNU GPL */ /* Gnome Print */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "libnr/n-art-bpath.h" #include "libnr/nr-rect.h" #include "libnr/nr-matrix.h" #include "libnr/nr-matrix-fns.h" #include "libnr/nr-path.h" #include "libnr/nr-pixblock.h" #include "display/canvas-bpath.h" #include #include #include #include #if OLDGnome #include #include #endif #include #include "enums.h" #include "document.h" #include "style.h" #include "sp-paint-server.h" #include "gnome.h" #include "extension/extension.h" #include "extension/system.h" static ArtBpath *nr_artpath_to_art_bpath(NArtBpath const *s); namespace Inkscape { namespace Extension { namespace Internal { PrintGNOME::PrintGNOME (void) { /* Nothing here */ } PrintGNOME::~PrintGNOME (void) { return; } unsigned int PrintGNOME::setup (Inkscape::Extension::Print *mod) { GnomePrintConfig *config; #if OLDGnome GtkWidget *dlg, *vbox, *sel; #endif config = gnome_print_config_default (); #if OLDGnome dlg = gtk_dialog_new_with_buttons (_("Select printer"), NULL, GTK_DIALOG_MODAL, GTK_STOCK_PRINT, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); vbox = GTK_DIALOG (dlg)->vbox; gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); sel = gnome_printer_selector_new (config); gtk_widget_show (sel); gtk_box_pack_start (GTK_BOX (vbox), sel, TRUE, TRUE, 0); btn = gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); if (btn != GTK_RESPONSE_OK) return FALSE; #endif _gpc = gnome_print_context_new (config); gnome_print_config_unref (config); return TRUE; } unsigned int PrintGNOME::set_preview (Inkscape::Extension::Print *mod) { #if OLDGnome SPPrintContext ctx; GnomePrintContext *gpc; GnomePrintMaster *gpm; GtkWidget *gpmp; gchar *title; gpm = gnome_print_master_new(); _gpc = gnome_print_master_get_context (gpm); g_return_if_fail (gpm != NULL); g_return_if_fail (gpc != NULL); /* Print document */ gnome_print_beginpage (gpc, SP_DOCUMENT_NAME (doc)); gnome_print_translate (gpc, 0.0, sp_document_height (doc)); /* From desktop points to document pixels */ gnome_print_scale (gpc, 0.8, -0.8); sp_item_invoke_print (SP_ITEM (sp_document_root (doc)), &ctx); gnome_print_showpage (gpc); gnome_print_context_close (gpc); title = g_strdup_printf (_("Inkscape: Print Preview")); gpmp = gnome_print_master_preview_new (gpm, title); gtk_widget_show (GTK_WIDGET(gpmp)); gnome_print_master_close (gpm); g_free (title); #endif return 0; } unsigned int PrintGNOME::begin (Inkscape::Extension::Print *mod, SPDocument *doc) { gnome_print_beginpage (_gpc, (const guchar *)SP_DOCUMENT_NAME (doc)); gnome_print_translate (_gpc, 0.0, sp_document_height (doc)); /* From desktop points to document pixels */ gnome_print_scale (_gpc, 0.8, -0.8); return 0; } unsigned int PrintGNOME::finish (Inkscape::Extension::Print *mod) { gnome_print_showpage (_gpc); gnome_print_context_close (_gpc); return 0; } unsigned int PrintGNOME::bind (Inkscape::Extension::Print *mod, const NRMatrix *transform, float opacity) { gdouble t[6]; gnome_print_gsave(_gpc); t[0] = transform->c[0]; t[1] = transform->c[1]; t[2] = transform->c[2]; t[3] = transform->c[3]; t[4] = transform->c[4]; t[5] = transform->c[5]; gnome_print_concat (_gpc, t); /* fixme: Opacity? (lauris) */ return 0; } unsigned int PrintGNOME::release (Inkscape::Extension::Print *mod) { gnome_print_grestore (_gpc); return 0; } unsigned int PrintGNOME::comment (Inkscape::Extension::Print * module, const char * comment) { // ignore comment return 0; } unsigned int PrintGNOME::fill(Inkscape::Extension::Print *mod, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) { gdouble t[6]; /* CTM is for information purposes only */ /* We expect user coordinate system to be set up already */ t[0] = ctm->c[0]; t[1] = ctm->c[1]; t[2] = ctm->c[2]; t[3] = ctm->c[3]; t[4] = ctm->c[4]; t[5] = ctm->c[5]; if (style->fill.type == SP_PAINT_TYPE_COLOR) { float rgb[3], opacity; sp_color_get_rgb_floatv (&style->fill.value.color, rgb); gnome_print_setrgbcolor (_gpc, rgb[0], rgb[1], rgb[2]); /* fixme: */ opacity = SP_SCALE24_TO_FLOAT (style->fill_opacity.value) * SP_SCALE24_TO_FLOAT (style->opacity.value); gnome_print_setopacity (_gpc, opacity); ArtBpath * apath = nr_artpath_to_art_bpath(bpath->path); gnome_print_bpath (_gpc, apath, FALSE); g_free(apath); if (style->fill_rule.value == SP_WIND_RULE_EVENODD) { gnome_print_eofill (_gpc); } else { gnome_print_fill (_gpc); } } else if (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) { SPPainter *painter; NRRect dpbox; /* fixme: */ dpbox.x0 = pbox->x0; dpbox.y0 = pbox->y0; dpbox.x1 = pbox->x1; dpbox.y1 = pbox->y1; painter = sp_paint_server_painter_new(SP_STYLE_FILL_SERVER(style), // FIXME: the second matrix below must be the parent (context) transform. // I don't know what it must be for gnome-print. --bb ctm, NR::identity(), &dpbox); if (painter) { NRRect cbox; NRRectL ibox; NRMatrix d2i; double dd2i[6]; int x, y; nr_rect_d_intersect (&cbox, dbox, bbox); ibox.x0 = (long) cbox.x0; ibox.y0 = (long) cbox.y0; ibox.x1 = (long) (cbox.x1 + 0.9999); ibox.y1 = (long) (cbox.y1 + 0.9999); nr_matrix_invert (&d2i, ctm); gnome_print_gsave (_gpc); ArtBpath * apath = nr_artpath_to_art_bpath(bpath->path); gnome_print_bpath (_gpc, apath, FALSE); g_free(apath); if (style->fill_rule.value == SP_WIND_RULE_EVENODD) { gnome_print_eoclip (_gpc); } else { gnome_print_clip (_gpc); } dd2i[0] = d2i.c[0]; dd2i[1] = d2i.c[1]; dd2i[2] = d2i.c[2]; dd2i[3] = d2i.c[3]; dd2i[4] = d2i.c[4]; dd2i[5] = d2i.c[5]; gnome_print_concat (_gpc, dd2i); /* Now we are in desktop coordinates */ for (y = ibox.y0; y < ibox.y1; y+= 64) { for (x = ibox.x0; x < ibox.x1; x+= 64) { NRPixBlock pb; nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, x, y, x + 64, y + 64, TRUE); painter->fill (painter, &pb); gnome_print_gsave (_gpc); gnome_print_translate (_gpc, x, y + 64); gnome_print_scale (_gpc, 64, -64); gnome_print_rgbaimage (_gpc, NR_PIXBLOCK_PX (&pb), 64, 64, pb.rs); gnome_print_grestore (_gpc); nr_pixblock_release (&pb); } } gnome_print_grestore (_gpc); sp_painter_free (painter); } } return 0; } unsigned int PrintGNOME::stroke (Inkscape::Extension::Print *mod, const NRBPath *bpath, const NRMatrix *ctm, const SPStyle *style, const NRRect *pbox, const NRRect *dbox, const NRRect *bbox) { gdouble t[6]; /* CTM is for information purposes only */ /* We expect user coordinate system to be set up already */ t[0] = ctm->c[0]; t[1] = ctm->c[1]; t[2] = ctm->c[2]; t[3] = ctm->c[3]; t[4] = ctm->c[4]; t[5] = ctm->c[5]; if (style->stroke.type == SP_PAINT_TYPE_COLOR) { float rgb[3], opacity; sp_color_get_rgb_floatv (&style->stroke.value.color, rgb); gnome_print_setrgbcolor (_gpc, rgb[0], rgb[1], rgb[2]); /* fixme: */ opacity = SP_SCALE24_TO_FLOAT (style->stroke_opacity.value) * SP_SCALE24_TO_FLOAT (style->opacity.value); gnome_print_setopacity (_gpc, opacity); if (style->stroke_dash.n_dash > 0) { gnome_print_setdash (_gpc, style->stroke_dash.n_dash, style->stroke_dash.dash, style->stroke_dash.offset); } else { gnome_print_setdash (_gpc, 0, NULL, 0.0); } gnome_print_setlinewidth (_gpc, style->stroke_width.computed); gnome_print_setlinejoin (_gpc, style->stroke_linejoin.computed); gnome_print_setlinecap (_gpc, style->stroke_linecap.computed); ArtBpath * apath = nr_artpath_to_art_bpath(bpath->path); gnome_print_bpath (_gpc, apath, FALSE); g_free(apath); gnome_print_stroke (_gpc); } return 0; } unsigned int PrintGNOME::image (Inkscape::Extension::Print *mod, unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, const NRMatrix *transform, const SPStyle *style) { gdouble t[6]; t[0] = transform->c[0]; t[1] = transform->c[1]; t[2] = transform->c[2]; t[3] = transform->c[3]; t[4] = transform->c[4]; t[5] = transform->c[5]; gnome_print_gsave (_gpc); gnome_print_concat (_gpc, t); if (style->opacity.value != SP_SCALE24_MAX) { guchar *dpx, *d, *s; guint x, y; guint32 alpha; alpha = (guint32) floor (SP_SCALE24_TO_FLOAT (style->opacity.value) * 255.9999); dpx = g_new (guchar, w * h * 4); for (y = 0; y < h; y++) { s = px + y * rs; d = dpx + y * w * 4; memcpy (d, s, w * 4); for (x = 0; x < w; x++) { d[3] = (s[3] * alpha) / 255; s += 4; d += 4; } } gnome_print_rgbaimage (_gpc, dpx, w, h, w * 4); g_free (dpx); } else { gnome_print_rgbaimage (_gpc, px, w, h, rs); } gnome_print_grestore (_gpc); return 0; } #include "clear-n_.h" void PrintGNOME::init (void) { Inkscape::Extension::Extension * ext; /* SVG in */ ext = Inkscape::Extension::build_from_mem( "\n" "" N_("GNOME Print") "\n" "" SP_MODULE_KEY_PRINT_GNOME "\n" "\n" "", new PrintGNOME()); return; } } /* namespace Internal */ } /* namespace Extension */ } /* namespace Inkscape */ // Remember to free the result! static ArtBpath * nr_artpath_to_art_bpath(NArtBpath const *s) { int i; if (!s) { return NULL; } i = 0; while (s[i].code != NR_END) i += 1; ArtBpath* d = g_new (ArtBpath, i + 1); i = 0; while (s[i].code != NR_END) { d[i].code = (ArtPathcode)s[i].code; if (s[i].code == NR_CURVETO) { d[i].x1 = s[i].x1; d[i].y1 = s[i].y1; d[i].x2 = s[i].x2; d[i].y2 = s[i].y2; } d[i].x3 = s[i].x3; d[i].y3 = s[i].y3; i += 1; } d[i].code = ART_END; return d; }