#define __INKSCAPE_CTRLPOINT_C__ /* * Simple point * * Author: * Maximilian Albert * * Copyright (C) 2008 Maximilian Albert * * Released under GNU GPL */ #include "sp-canvas-util.h" #include "sp-ctrlpoint.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "display/cairo-utils.h" static void sp_ctrlpoint_class_init (SPCtrlPointClass *klass); static void sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint); static void sp_ctrlpoint_destroy (GtkObject *object); static void sp_ctrlpoint_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf); static SPCanvasItemClass *parent_class; GType sp_ctrlpoint_get_type (void) { static GType type = 0; if (!type) { GTypeInfo info = { sizeof(SPCtrlPointClass), NULL, NULL, (GClassInitFunc) sp_ctrlpoint_class_init, NULL, NULL, sizeof(SPCtrlPoint), 0, (GInstanceInitFunc) sp_ctrlpoint_init, NULL }; type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlPoint", &info, (GTypeFlags)0); } return type; } static void sp_ctrlpoint_class_init (SPCtrlPointClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); object_class->destroy = sp_ctrlpoint_destroy; item_class->update = sp_ctrlpoint_update; item_class->render = sp_ctrlpoint_render; } static void sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint) { ctrlpoint->rgba = 0x0000ff7f; ctrlpoint->pt[Geom::X] = ctrlpoint->pt[Geom::Y] = 0.0; ctrlpoint->item=NULL; ctrlpoint->radius = 2; } static void sp_ctrlpoint_destroy (GtkObject *object) { g_return_if_fail (object != NULL); g_return_if_fail (SP_IS_CTRLPOINT (object)); SPCtrlPoint *ctrlpoint = SP_CTRLPOINT (object); ctrlpoint->item=NULL; if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf) { SPCtrlPoint *cp = SP_CTRLPOINT (item); if (!buf->ct) return; sp_canvas_prepare_buffer (buf); guint32 rgba = cp->rgba; cairo_set_source_rgba(buf->ct, SP_RGBA32_B_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_R_F(rgba), SP_RGBA32_A_F(rgba)); cairo_set_line_width(buf->ct, 1); cairo_new_path(buf->ct); Geom::Point pt = cp->pt * cp->affine; cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->radius, 0.0, 2 * M_PI); cairo_stroke(buf->ct); } static void sp_ctrlpoint_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags) { SPCtrlPoint *cp = SP_CTRLPOINT (item); sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); if (parent_class->update) (* parent_class->update) (item, affine, flags); sp_canvas_item_reset_bounds (item); cp->affine = affine; Geom::Point pt = cp->pt * affine; item->x1 = pt[Geom::X] - cp->radius; item->y1 = pt[Geom::Y] - cp->radius; item->x2 = pt[Geom::X] + cp->radius; item->y2 = pt[Geom::Y] + cp->radius; sp_canvas_request_redraw (item->canvas, (int)item->x1 - 15, (int)item->y1 - 15, (int)item->x1 + 15, (int)item->y1 + 15); } void sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba) { g_return_if_fail (cp != NULL); g_return_if_fail (SP_IS_CTRLPOINT (cp)); if (rgba != cp->rgba) { SPCanvasItem *item; cp->rgba = rgba; item = SP_CANVAS_ITEM (cp); sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); } } #define EPSILON 1e-6 #define DIFFER(a,b) (fabs ((a) - (b)) > EPSILON) void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y) { g_return_if_fail (cp != NULL); g_return_if_fail (SP_IS_CTRLPOINT (cp)); if (DIFFER (x, cp->pt[Geom::X]) || DIFFER (y, cp->pt[Geom::Y])) { cp->pt[Geom::X] = x; cp->pt[Geom::Y] = y; sp_canvas_item_request_update (SP_CANVAS_ITEM (cp)); } } void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt) { sp_ctrlpoint_set_coords(cp, pt[Geom::X], pt[Geom::Y]); } void sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r) { cp->radius = r; } /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :