summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/gnome.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/gnome.cpp')
-rw-r--r--src/extension/internal/gnome.cpp443
1 files changed, 443 insertions, 0 deletions
diff --git a/src/extension/internal/gnome.cpp b/src/extension/internal/gnome.cpp
new file mode 100644
index 000000000..d81dfa95e
--- /dev/null
+++ b/src/extension/internal/gnome.cpp
@@ -0,0 +1,443 @@
+#define __SP_GNOME_C__
+
+/*
+ * Gnome stuff
+ *
+ * Author:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * Ted Gould <ted@gould.cx>
+ *
+ *
+ * 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 <string.h>
+
+#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 <glib.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtkstock.h>
+
+#if OLDGnome
+#include <libgnomeprint/gnome-print-master.h>
+#include <libgnomeprintui/gnome-print-master-preview.h>
+#endif
+
+#include <glibmm/i18n.h>
+#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;
+}
+
+void
+PrintGNOME::init (void)
+{
+ Inkscape::Extension::Extension * ext;
+
+ /* SVG in */
+ ext = Inkscape::Extension::build_from_mem(
+ "<inkscape-extension>\n"
+ "<name>GNOME Print</name>\n"
+ "<id>" SP_MODULE_KEY_PRINT_GNOME "</id>\n"
+ "<print/>\n"
+ "</inkscape-extension>", 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 = nr_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;
+}
+