/* multiply a projective matrix by an affine matrix */
TransfMat3x4
TransfMat3x4::operator*(Geom::Matrix const &A) const {
    TransfMat3x4 ret;

    // Is it safe to always use the currently active document?
    double h = sp_document_height(inkscape_active_document());

    /*
     * Note: The strange multiplication involving the document height is due to the buggy
     *       intertwining of SVG and document coordinates. Essentially, what we do is first
     *       convert from "real-world" to SVG coordinates, then apply the transformation A
     *       (by multiplying with the Geom::Matrix) and then convert back from SVG to real-world
     *       coordinates. Maybe there is even a more Inkscape-ish way to achieve this?
     *       Once Inkscape has gotton rid of the two different coordiate systems, we can change
     *       this function to an ordinary matrix multiplication.
     */
    for (int j = 0; j < 4; ++j) {
        ret.tmat[0][j] = A[0]*tmat[0][j] + A[2]*(h*tmat[2][j] - tmat[1][j]) + A[4]*tmat[2][j];
        ret.tmat[1][j] = A[1]*tmat[0][j] + A[3]*(h*tmat[2][j] - tmat[1][j]) + A[5]*tmat[2][j];
        ret.tmat[2][j] = tmat[2][j];

        ret.tmat[1][j] = h*ret.tmat[2][j] - ret.tmat[1][j]; // switch back from SVG to desktop coordinates
    }

    return ret;
}
Beispiel #2
0
void
sp_help_about (void)
{
	SPDocument *doc;
	SPObject *title;
	GtkWidget *v;
	gint width, height;

	if (!w) {

	doc = sp_document_new (INKSCAPE_PIXMAPDIR "/about.svg", FALSE, TRUE);
	g_return_if_fail (doc != NULL);
	title = sp_document_lookup_id (doc, "title");
	if (title && SP_IS_TEXT (title)) {
		gchar *t;
		t = g_strdup_printf ("Inkscape %s", INKSCAPE_VERSION);
		sp_text_set_repr_text_multiline (SP_TEXT (title), t);
		g_free (t);
	}
	sp_document_ensure_up_to_date (doc);

	w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title (GTK_WINDOW (w), _("About Inkscape"));

        width = INK_STATIC_CAST( gint, CLAMP( sp_document_width(doc), WINDOW_MIN, WINDOW_MAX ) );
        height = INK_STATIC_CAST( gint, CLAMP( sp_document_height(doc), WINDOW_MIN, WINDOW_MAX ) );
        gtk_window_set_default_size (GTK_WINDOW (w), width, height );
				gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER);

#if 1
	gtk_window_set_policy (GTK_WINDOW (w), TRUE, TRUE, FALSE);
#endif
	gtk_signal_connect (GTK_OBJECT (w), "delete_event", GTK_SIGNAL_FUNC (sp_help_about_delete), NULL);

	v = sp_svg_view_widget_new (doc);
	sp_svg_view_widget_set_resize (SP_SVG_VIEW_WIDGET (v), FALSE, sp_document_width (doc), sp_document_height (doc));
	sp_document_unref (doc);
	gtk_widget_show (v);
	gtk_container_add (GTK_CONTAINER (w), v);

	}

	gtk_window_present ((GtkWindow *) w);
}
Beispiel #3
0
Print::Print(SPDocument *doc, SPItem *base) :
    _doc (doc),
    _base (base)
{
    g_assert (_doc);
    g_assert (_base);

    _printop = gtk_print_operation_new ();

    // set up dialog title, based on document name
    gchar *jobname = _doc->name ? _doc->name : _("SVG Document");
    Glib::ustring title = _("Print");
    title += " ";
    title += jobname;
    gtk_print_operation_set_job_name (_printop, title.c_str());

    // set up paper size to match the document size
    gtk_print_operation_set_unit (_printop, GTK_UNIT_POINTS);
    GtkPageSetup *page_setup = gtk_page_setup_new();
    gdouble doc_width = sp_document_width(_doc) * PT_PER_PX;
    gdouble doc_height = sp_document_height(_doc) * PT_PER_PX;
    GtkPaperSize *paper_size = gtk_paper_size_new_custom("custom", "custom",
                                doc_width, doc_height, GTK_UNIT_POINTS);
    gtk_page_setup_set_paper_size (page_setup, paper_size);
#ifndef WIN32
    gtk_print_operation_set_default_page_setup (_printop, page_setup);
#endif
    gtk_print_operation_set_use_full_page (_printop, TRUE);

    // set up signals
    _workaround._doc = _doc;
    _workaround._base = _base;
    _workaround._tab = &_tab;
    g_signal_connect (_printop, "create-custom-widget", G_CALLBACK (create_custom_widget), _tab.gobj());
    g_signal_connect (_printop, "begin-print", G_CALLBACK (begin_print), NULL);
    g_signal_connect (_printop, "draw-page", G_CALLBACK (draw_page), &_workaround);

    // build custom preferences tab
    gtk_print_operation_set_custom_tab_label (_printop, _("Rendering"));
}
/**
 * Given a Geom::Rect that may, for example, correspond to the bbox of an object,
 * this function fits the canvas to that rect by resizing the canvas
 * and translating the document root into position.
 */
void SPDocument::fitToRect(Geom::Rect const &rect)
{
    double const w = rect.width();
    double const h = rect.height();

    double const old_height = sp_document_height(this);
    SPUnit const &px(sp_unit_get_by_id(SP_UNIT_PX));
    sp_document_set_width(this, w, &px);
    sp_document_set_height(this, h, &px);

    Geom::Translate const tr(Geom::Point(0, (old_height - h))
                             - to_2geom(rect.min()));
    SP_GROUP(root)->translateChildItems(tr);
    SPNamedView *nv = sp_document_namedview(this, 0);
    if(nv) {
        Geom::Translate tr2(-rect.min());
        nv->translateGuides(tr2);

        // update the viewport so the drawing appears to stay where it was
        nv->scrollAllDesktops(-tr2[0], tr2[1], false);
    }
}
Geom::Point sp_document_dimensions(SPDocument *doc)
{
    return Geom::Point(sp_document_width(doc), sp_document_height(doc));
}
Beispiel #6
0
static void
draw_page (GtkPrintOperation */*operation*/,
           GtkPrintContext   *context,
           gint               /*page_nr*/,
           gpointer           user_data)
{
    struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data;
    //printf("%s %d\n",__FUNCTION__, page_nr);

    if (junk->_tab->as_bitmap()) {
        // Render as exported PNG
        gdouble width = sp_document_width(junk->_doc);
        gdouble height = sp_document_height(junk->_doc);
        gdouble dpi = junk->_tab->bitmap_dpi();
        std::string tmp_png;
        std::string tmp_base = "inkscape-print-png-XXXXXX";

        int tmp_fd;
        if ( (tmp_fd = Inkscape::IO::file_open_tmp (tmp_png, tmp_base)) >= 0) {
            close(tmp_fd);

            guint32 bgcolor = 0x00000000;
            Inkscape::XML::Node *nv = sp_repr_lookup_name (junk->_doc->rroot, "sodipodi:namedview");
            if (nv && nv->attribute("pagecolor"))
                bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
            if (nv && nv->attribute("inkscape:pageopacity"))
                bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));

            sp_export_png_file(junk->_doc, tmp_png.c_str(), 0.0, 0.0,
                width, height,
                (unsigned long)(width * dpi / PX_PER_IN),
                (unsigned long)(height * dpi / PX_PER_IN),
                dpi, dpi, bgcolor, NULL, NULL, true, NULL);

            // This doesn't seem to work:
            //context->set_cairo_context ( Cairo::Context::create (Cairo::ImageSurface::create_from_png (tmp_png) ), dpi, dpi );
            //
            // so we'll use a surface pattern blat instead...
            //
            // but the C++ interface isn't implemented in cairomm:
            //context->get_cairo_context ()->set_source_surface(Cairo::ImageSurface::create_from_png (tmp_png) );
            //
            // so do it in C:
            {
                Cairo::RefPtr<Cairo::ImageSurface> png = Cairo::ImageSurface::create_from_png (tmp_png);
                cairo_t *cr = gtk_print_context_get_cairo_context (context);
		cairo_matrix_t m;
		cairo_get_matrix(cr, &m);
		cairo_scale(cr, PT_PER_IN / dpi, PT_PER_IN / dpi);
                // FIXME: why is the origin offset??
                cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0);
		cairo_paint(cr);
		cairo_set_matrix(cr, &m);
            }

            // Clean up
            unlink (tmp_png.c_str());
        }
        else {
            g_warning(_("Could not open temporary PNG for bitmap printing"));
        }
    }
    else {
        // Render as vectors
        Inkscape::Extension::Internal::CairoRenderer renderer;
        Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext();

        // ctx->setPSLevel(CAIRO_PS_LEVEL_3);
        ctx->setTextToPath(false);
        ctx->setFilterToBitmap(true);
        ctx->setBitmapResolution(72);

        cairo_t *cr = gtk_print_context_get_cairo_context (context);
        cairo_surface_t *surface = cairo_get_target(cr);


/**
	Call cairo_win32_printing_surface directly as a workaround until GTK uses this call.
	When GTK uses cairo_win32_printing_surface this automatically reverts.
*/
#ifdef WIN32
        if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_WIN32) {
        HDC dc = cairo_win32_surface_get_dc (surface);
        surface = _cairo_win32_printing_surface_create (dc);
        }
#endif

        bool ret = ctx->setSurfaceTarget (surface, true);        if (ret) {
            ret = renderer.setupDocument (ctx, junk->_doc, TRUE, NULL);
            if (ret) {
                renderer.renderItem(ctx, junk->_base);
                ret = ctx->finish();
            }
            else {
                g_warning(_("Could not set up Document"));
            }
        }
        else {
            g_warning(_("Failed to set CairoRenderContext"));
        }

        // Clean up
        renderer.destroyContext(ctx);
    }

}
Beispiel #7
0
void
sp_align_arrange_clicked (GtkWidget *widget, const gchar *aligns)
{
	float mx0, mx1, my0, my1;
	float sx0, sx1, sy0, sy1;
	SPDesktop * desktop;
	SPSelection * selection;
	GSList * slist;
	SPItem * master, * item;
	NRRectF b;
	NRPointF mp, sp;
	GSList * l;
	gboolean changed;

	mx0 = 0.5 * aligns[0];
	mx1 = 0.5 * aligns[1];
	my0 = 0.5 * aligns[2];
	my1 = 0.5 * aligns[3];
	sx0 = 0.5 * aligns[4];
	sx1 = 0.5 * aligns[5];
	sy0 = 0.5 * aligns[6];
	sy1 = 0.5 * aligns[7];

	desktop = SP_ACTIVE_DESKTOP;
	if (!desktop) return;

	selection = SP_DT_SELECTION (desktop);
	slist = (GSList *) sp_selection_item_list (selection);
	if (!slist) return;

	switch (base) {
	case SP_ALIGN_LAST:
	case SP_ALIGN_FIRST:
	case SP_ALIGN_BIGGEST:
	case SP_ALIGN_SMALLEST:
		if (!slist->next) return;
		slist = g_slist_copy (slist);
		master = sp_quick_align_find_master (slist, (mx0 != 0.0) || (mx1 != 0.0));
		slist = g_slist_remove (slist, master);
		sp_item_bbox_desktop (master, &b);
		mp.x = mx0 * b.x0 + mx1 * b.x1;
		mp.y = my0 * b.y0 + my1 * b.y1;
		break;
	case SP_ALIGN_PAGE:
		slist = g_slist_copy (slist);
		mp.x = mx1 * sp_document_width (SP_DT_DOCUMENT (desktop));
		mp.y = my1 * sp_document_height (SP_DT_DOCUMENT (desktop));
		break;
	case SP_ALIGN_DRAWING:
		slist = g_slist_copy (slist);
		sp_item_bbox_desktop ((SPItem *) sp_document_root (SP_DT_DOCUMENT (desktop)), &b);
		mp.x = mx0 * b.x0 + mx1 * b.x1;
		mp.y = my0 * b.y0 + my1 * b.y1;
		break;
	case SP_ALIGN_SELECTION:
		slist = g_slist_copy (slist);
		sp_selection_bbox (selection, &b);
		mp.x = mx0 * b.x0 + mx1 * b.x1;
		mp.y = my0 * b.y0 + my1 * b.y1;
		break;
	default:
		g_assert_not_reached ();
		break;
	};

	changed = FALSE;

	for (l = slist; l != NULL; l = l->next) {
		item = (SPItem *) l->data;
		sp_item_bbox_desktop (item, &b);
		sp.x = sx0 * b.x0 + sx1 * b.x1;
		sp.y = sy0 * b.y0 + sy1 * b.y1;

		if ((fabs (mp.x - sp.x) > 1e-9) || (fabs (mp.y - sp.y) > 1e-9)) {
			sp_item_move_rel (item, mp.x - sp.x, mp.y - sp.y);
			changed = TRUE;
		}
	}

	g_slist_free (slist);

	if (changed) {
		sp_selection_changed (selection);
		sp_document_done (SP_DT_DOCUMENT (desktop));
	}
}