Code

Removal of old grid code - fully enabled new grid code.
[inkscape.git] / src / display / canvas-grid.cpp
index f343077c3550c3e5aed36afc4f10ead5a5a80842..7db2d4020dfd46642ee1557c680e1426df08d358 100644 (file)
@@ -135,25 +135,15 @@ grid_canvasitem_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned i
         NULL  /* order_changed */
     };
 
-CanvasGrid::CanvasGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr)
+CanvasGrid::CanvasGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr)
 {
-    //create canvasitem
-    // FIXME: probably this creation has to be done on demand. I think for multiple desktops it is best if each has their own canvasitem, but share the same CanvasGrid object.
-    canvasitem = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(sp_desktop_grid(desktop), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) );
-    gtk_object_ref(GTK_OBJECT(canvasitem));    // since we're keeping a copy, we need to bump up the ref count
-    canvasitem->grid = this;
-
-    snapenabled = false;
-    visible = false;
-
-//    sp_canvas_item_hide(canvasitem);
-
     repr = in_repr;
     if (repr) {
         repr->addListener (&_repr_events, this);
     }
-    
-    namedview = sp_desktop_namedview(desktop);
+
+    namedview = nv;
+    canvasitems = NULL;
 }
 
 CanvasGrid::~CanvasGrid()
@@ -162,28 +152,28 @@ CanvasGrid::~CanvasGrid()
         repr->removeListenerByData (this);
     }
 
-    sp_canvas_item_hide(canvasitem);
-   // deref canvasitem
-   gtk_object_unref(GTK_OBJECT(canvasitem));
-   g_free(canvasitem);
+    while (canvasitems) {
+        gtk_object_destroy(GTK_OBJECT(canvasitems->data));
+        canvasitems = g_slist_remove(canvasitems, canvasitems->data);
+    }
 }
 
 /*
-*  writes an <inkscape:grid> child to repr. 
+*  writes an <inkscape:grid> child to repr.
 */
-void 
+void
 CanvasGrid::writeNewGridToRepr(Inkscape::XML::Node * repr, const char * gridtype)
 {
     if (!repr) return;
     if (!gridtype) return;
-    
+
     // first create the child xml node, then hook it to repr. This order is important, to not set off listeners to repr before the new node is complete.
-    
+
     Inkscape::XML::Document *xml_doc = sp_document_repr_doc(sp_desktop_document(SP_ACTIVE_DESKTOP));
     Inkscape::XML::Node *newnode;
     newnode = xml_doc->createElement("inkscape:grid");
     newnode->setAttribute("type",gridtype);
-    
+
     repr->appendChild(newnode);
 
     // FIXME: add this to history?
@@ -192,57 +182,48 @@ CanvasGrid::writeNewGridToRepr(Inkscape::XML::Node * repr, const char * gridtype
 }
 
 /*
-* Creates a new CanvasGrid object of type gridtype 
+* Creates a new CanvasGrid object of type gridtype
 */
-CanvasGrid* 
-CanvasGrid::NewGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr, const char * gridtype)
+CanvasGrid*
+CanvasGrid::NewGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, const char * gridtype)
 {
-    if (!desktop) return NULL;
     if (!in_repr) return NULL;
     if (!gridtype) return NULL;
-    
+
     if (!strcmp(gridtype,"xygrid")) {
-        return (CanvasGrid*) new CanvasXYGrid(desktop, in_repr);
+        return (CanvasGrid*) new CanvasXYGrid(nv, in_repr);
     } else if (!strcmp(gridtype,"axonometric")) {
-        return (CanvasGrid*) new CanvasAxonomGrid(desktop, in_repr);
+        return (CanvasGrid*) new CanvasAxonomGrid(nv, in_repr);
     }
-    
+
     return NULL;
 }
 
 
-void
-CanvasGrid::hide()
-{
-    sp_canvas_item_hide(canvasitem);
-    visible = false;
-    disable_snapping(); // temporary hack, because at the moment visibilty and snapping are linked
-}
-
-void
-CanvasGrid::show()
+/**
+*  creates a new grid canvasitem for the SPDesktop given as parameter. Keeps a link to this canvasitem in the canvasitems list.
+*/
+GridCanvasItem *
+CanvasGrid::createCanvasItem(SPDesktop * desktop)
 {
-    sp_canvas_item_show(canvasitem);
-    visible = true;
-    enable_snapping(); // temporary hack, because at the moment visibilty and snapping are linked
-}
+    if (!desktop) return NULL;
+    //Johan: I think for multiple desktops it is best if each has their own canvasitem, but share the same CanvasGrid object; that is what this function is for.
 
-void 
-CanvasGrid::set_visibility(bool visible)
-{
-    this->visible = visible;
-    if(visible) {
-        show();
-    } else {
-        hide();
+    // check if there is already a canvasitem on this desktop linking to this grid
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        if ( sp_desktop_gridgroup(desktop) == SP_CANVAS_GROUP(SP_CANVAS_ITEM(l->data)->parent) ) {
+            return NULL;
+        }
     }
-}
 
-void
-CanvasGrid::toggle_visibility()
-{
-    visible = !visible;
-    set_visibility(visible);
+    GridCanvasItem * item = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(sp_desktop_gridgroup(desktop), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) );
+    item->grid = this;
+    sp_canvas_item_show(SP_CANVAS_ITEM(item));
+
+    gtk_object_ref(GTK_OBJECT(item));    // since we're keeping a link to this item, we need to bump up the ref count
+    canvasitems = g_slist_prepend(canvasitems, item);
+
+    return item;
 }
 
 void
@@ -259,8 +240,52 @@ CanvasGrid::on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key,
 // ##########################################################
 //   CanvasXYGrid
 
-static void grid_hline (SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba);
-static void grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba);
+static void
+grid_hline (SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba)
+{
+    if ((y >= buf->rect.y0) && (y < buf->rect.y1)) {
+        guint r, g, b, a;
+        gint x0, x1, x;
+        guchar *p;
+        r = NR_RGBA32_R (rgba);
+        g = NR_RGBA32_G (rgba);
+        b = NR_RGBA32_B (rgba);
+        a = NR_RGBA32_A (rgba);
+        x0 = MAX (buf->rect.x0, xs);
+        x1 = MIN (buf->rect.x1, xe + 1);
+        p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3;
+        for (x = x0; x < x1; x++) {
+            p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
+            p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
+            p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
+            p += 3;
+        }
+    }
+}
+
+static void
+grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba)
+{
+    if ((x >= buf->rect.x0) && (x < buf->rect.x1)) {
+        guint r, g, b, a;
+        gint y0, y1, y;
+        guchar *p;
+        r = NR_RGBA32_R(rgba);
+        g = NR_RGBA32_G (rgba);
+        b = NR_RGBA32_B (rgba);
+        a = NR_RGBA32_A (rgba);
+        y0 = MAX (buf->rect.y0, ys);
+        y1 = MIN (buf->rect.y1, ye + 1);
+        p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
+        for (y = y0; y < y1; y++) {
+            p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
+            p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
+            p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
+            p += buf->buf_rowstride;
+        }
+    }
+}
+
 
 
 /**
@@ -310,8 +335,8 @@ attach_all (Gtk::Table &table, const Gtk::Widget *arr[], unsigned size, int star
     }
 }
 
-CanvasXYGrid::CanvasXYGrid (SPDesktop *desktop, Inkscape::XML::Node * in_repr)
-    : CanvasGrid(desktop, in_repr), table(1, 1)
+CanvasXYGrid::CanvasXYGrid (SPNamedView * nv, Inkscape::XML::Node * in_repr)
+    : CanvasGrid(nv, in_repr), table(1, 1)
 {
     origin[NR::X] = origin[NR::Y] = 0.0;
 //            nv->gridcolor = (nv->gridcolor & 0xff) | (DEFAULTGRIDCOLOR & 0xffffff00);
@@ -322,9 +347,9 @@ CanvasXYGrid::CanvasXYGrid (SPDesktop *desktop, Inkscape::XML::Node * in_repr)
     empspacing = 5;
     spacing[NR::X] = spacing[NR::Y] = 8.0;
     gridunit = &sp_unit_get_by_id(SP_UNIT_PX);
-    
+
     snapper = new CanvasXYGridSnapper(this, namedview, 0);
-    
+
     // initialize widgets:
     vbox.set_border_width(2);
     table.set_spacings(2);
@@ -487,7 +512,9 @@ CanvasXYGrid::readRepr()
         empspacing = atoi(value);
     }
 
-    sp_canvas_item_request_update (canvasitem);
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
+    }
 
     return;
 }
@@ -546,7 +573,7 @@ CanvasXYGrid::updateWidgets()
     _rsi.setValue (empspacing);
 
     _wr.setUpdating (false);
-    
+
     return;
 }
 
@@ -640,7 +667,7 @@ CanvasXYGridSnapper::CanvasXYGridSnapper(CanvasXYGrid *grid, SPNamedView const *
     this->grid = grid;
 }
 
-LineSnapper::LineList 
+LineSnapper::LineList
 CanvasXYGridSnapper::_getSnapLines(NR::Point const &p) const
 {
     LineList s;
@@ -674,313 +701,6 @@ CanvasXYGridSnapper::_getSnapLines(NR::Point const &p) const
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-enum {
-    ARG_0,
-    ARG_ORIGINX,
-    ARG_ORIGINY,
-    ARG_SPACINGX,
-    ARG_SPACINGY,
-    ARG_COLOR,
-    ARG_EMPCOLOR,
-    ARG_EMPSPACING
-};
-
-
-static void cxygrid_class_init (CXYGridClass *klass);
-static void cxygrid_init (CXYGrid *grid);
-static void cxygrid_destroy (GtkObject *object);
-static void cxygrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-static void cxygrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags);
-static void cxygrid_render (SPCanvasItem *item, SPCanvasBuf *buf);
-
-//static SPCanvasItemClass * parent_class;
-
-GtkType
-cxygrid_get_type (void)
-{
-    static GtkType cxygrid_type = 0;
-
-    if (!cxygrid_type) {
-        GtkTypeInfo cxygrid_info = {
-            "CXYGrid",
-            sizeof (CXYGrid),
-            sizeof (CXYGridClass),
-            (GtkClassInitFunc) cxygrid_class_init,
-            (GtkObjectInitFunc) cxygrid_init,
-            NULL, NULL,
-            (GtkClassInitFunc) NULL
-        };
-        cxygrid_type = gtk_type_unique (sp_canvas_item_get_type (), &cxygrid_info);
-    }
-    return cxygrid_type;
-}
-
-static void
-cxygrid_class_init (CXYGridClass *klass)
-{
-    GtkObjectClass *object_class;
-    SPCanvasItemClass *item_class;
-
-    object_class = (GtkObjectClass *) klass;
-    item_class = (SPCanvasItemClass *) klass;
-
-    parent_class = (SPCanvasItemClass*)gtk_type_class (sp_canvas_item_get_type ());
-
-    gtk_object_add_arg_type ("CXYGrid::originx", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINX);
-    gtk_object_add_arg_type ("CXYGrid::originy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINY);
-    gtk_object_add_arg_type ("CXYGrid::spacingx", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_SPACINGX);
-    gtk_object_add_arg_type ("CXYGrid::spacingy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_SPACINGY);
-    gtk_object_add_arg_type ("CXYGrid::color", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_COLOR);
-    gtk_object_add_arg_type ("CXYGrid::empcolor", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPCOLOR);
-    gtk_object_add_arg_type ("CXYGrid::empspacing", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPSPACING);
-
-    object_class->destroy = cxygrid_destroy;
-    object_class->set_arg = cxygrid_set_arg;
-
-    item_class->update = cxygrid_update;
-    item_class->render = cxygrid_render;
-}
-
-static void
-cxygrid_init (CXYGrid *grid)
-{
-    grid->origin[NR::X] = grid->origin[NR::Y] = 0.0;
-    grid->spacing[NR::X] = grid->spacing[NR::Y] = 8.0;
-    grid->color = 0x0000ff7f;
-    grid->empcolor = 0x3F3FFF40;
-    grid->empspacing = 5;
-}
-
-static void
-cxygrid_destroy (GtkObject *object)
-{
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (INKSCAPE_IS_CXYGRID (object));
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void
-cxygrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
-    SPCanvasItem *item = SP_CANVAS_ITEM (object);
-    CXYGrid *grid = INKSCAPE_CXYGRID (object);
-
-    switch (arg_id) {
-    case ARG_ORIGINX:
-        grid->origin[NR::X] = GTK_VALUE_DOUBLE (* arg);
-        sp_canvas_item_request_update (item);
-        break;
-    case ARG_ORIGINY:
-        grid->origin[NR::Y] = GTK_VALUE_DOUBLE (* arg);
-        sp_canvas_item_request_update (item);
-        break;
-    case ARG_SPACINGX:
-        grid->spacing[NR::X] = GTK_VALUE_DOUBLE (* arg);
-        if (grid->spacing[NR::X] < 0.01) grid->spacing[NR::X] = 0.01;
-        sp_canvas_item_request_update (item);
-        break;
-    case ARG_SPACINGY:
-        grid->spacing[NR::Y] = GTK_VALUE_DOUBLE (* arg);
-        if (grid->spacing[NR::Y] < 0.01) grid->spacing[NR::Y] = 0.01;
-        sp_canvas_item_request_update (item);
-        break;
-    case ARG_COLOR:
-        grid->color = GTK_VALUE_INT (* arg);
-        sp_canvas_item_request_update (item);
-        break;
-    case ARG_EMPCOLOR:
-        grid->empcolor = GTK_VALUE_INT (* arg);
-        sp_canvas_item_request_update (item);
-        break;
-    case ARG_EMPSPACING:
-        grid->empspacing = GTK_VALUE_INT (* arg);
-        // std::cout << "Emphasis Spacing: " << grid->empspacing << std::endl;
-        sp_canvas_item_request_update (item);
-        break;
-    default:
-        break;
-    }
-}
-
-static void
-grid_hline (SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba)
-{
-    if ((y >= buf->rect.y0) && (y < buf->rect.y1)) {
-        guint r, g, b, a;
-        gint x0, x1, x;
-        guchar *p;
-        r = NR_RGBA32_R (rgba);
-        g = NR_RGBA32_G (rgba);
-        b = NR_RGBA32_B (rgba);
-        a = NR_RGBA32_A (rgba);
-        x0 = MAX (buf->rect.x0, xs);
-        x1 = MIN (buf->rect.x1, xe + 1);
-        p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3;
-        for (x = x0; x < x1; x++) {
-            p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
-            p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
-            p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
-            p += 3;
-        }
-    }
-}
-
-static void
-grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba)
-{
-    if ((x >= buf->rect.x0) && (x < buf->rect.x1)) {
-        guint r, g, b, a;
-        gint y0, y1, y;
-        guchar *p;
-        r = NR_RGBA32_R(rgba);
-        g = NR_RGBA32_G (rgba);
-        b = NR_RGBA32_B (rgba);
-        a = NR_RGBA32_A (rgba);
-        y0 = MAX (buf->rect.y0, ys);
-        y1 = MIN (buf->rect.y1, ye + 1);
-        p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
-        for (y = y0; y < y1; y++) {
-            p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
-            p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
-            p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
-            p += buf->buf_rowstride;
-        }
-    }
-}
-
-/**
-    \brief  This function renders the grid on a particular canvas buffer
-    \param  item  The grid to render on the buffer
-    \param  buf   The buffer to render the grid on
-
-    This function gets called a touch more than you might believe,
-    about once per tile.  This means that it could probably be optimized
-    and help things out.
-
-    Basically this function has to determine where in the canvas it is,
-    and how that associates with the grid.  It does this first by looking
-    at the bounding box of the buffer, and then calculates where the grid
-    starts in that buffer.  It will then step through grid lines until
-    it is outside of the buffer.
-
-    For each grid line it is drawn using the function \c sp_grid_hline
-    or \c sp_grid_vline.  These are convience functions for the sake
-    of making the function easier to read.
-
-    Also, there are emphisized lines on the grid.  While the \c syg and
-    \c sxg variable track grid positioning, the \c xlinestart and \c
-    ylinestart variables track the 'count' of what lines they are.  If
-    that count is a multiple of the line seperation between emphisis
-    lines, then that line is drawn in the emphisis color.
-*/
-static void
-cxygrid_render (SPCanvasItem * item, SPCanvasBuf * buf)
-{
-    CXYGrid *grid = INKSCAPE_CXYGRID (item);
-
-    sp_canvas_prepare_buffer (buf);
-
-    const gdouble sxg = floor ((buf->rect.x0 - grid->ow[NR::X]) / grid->sw[NR::X]) * grid->sw[NR::X] + grid->ow[NR::X];
-    const gint  xlinestart = (gint) Inkscape::round((sxg - grid->ow[NR::X]) / grid->sw[NR::X]);
-    const gdouble syg = floor ((buf->rect.y0 - grid->ow[NR::Y]) / grid->sw[NR::Y]) * grid->sw[NR::Y] + grid->ow[NR::Y];
-    const gint  ylinestart = (gint) Inkscape::round((syg - grid->ow[NR::Y]) / grid->sw[NR::Y]);
-
-    gint ylinenum;
-    gdouble y;
-    for (y = syg, ylinenum = ylinestart; y < buf->rect.y1; y += grid->sw[NR::Y], ylinenum++) {
-        const gint y0 = (gint) Inkscape::round(y);
-
-        if (!grid->scaled[NR::Y] && (ylinenum % grid->empspacing) == 0) {
-            grid_hline (buf, y0, buf->rect.x0, buf->rect.x1 - 1, grid->empcolor);
-        } else {
-            grid_hline (buf, y0, buf->rect.x0, buf->rect.x1 - 1, grid->color);
-        }
-    }
-
-    gint xlinenum;
-    gdouble x;
-    for (x = sxg, xlinenum = xlinestart; x < buf->rect.x1; x += grid->sw[NR::X], xlinenum++) {
-        const gint ix = (gint) Inkscape::round(x);
-        if (!grid->scaled[NR::X] && (xlinenum % grid->empspacing) == 0) {
-            grid_vline (buf, ix, buf->rect.y0, buf->rect.y1, grid->empcolor);
-        } else {
-            grid_vline (buf, ix, buf->rect.y0, buf->rect.y1, grid->color);
-        }
-    }
-}
-
-static void
-cxygrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags)
-{
-    CXYGrid *grid = INKSCAPE_CXYGRID (item);
-
-    if (parent_class->update)
-        (* parent_class->update) (item, affine, flags);
-
-    grid->ow = grid->origin * affine;
-    grid->sw = grid->spacing * affine;
-    grid->sw -= NR::Point(affine[4], affine[5]);
-
-    for(int dim = 0; dim < 2; dim++) {
-        gint scaling_factor = grid->empspacing;
-
-        if (scaling_factor <= 1)
-            scaling_factor = 5;
-
-        grid->scaled[dim] = FALSE;
-        grid->sw[dim] = fabs (grid->sw[dim]);
-        while (grid->sw[dim] < 8.0) {
-            grid->scaled[dim] = TRUE;
-            grid->sw[dim] *= scaling_factor;
-            /* First pass, go up to the major line spacing, then
-               keep increasing by two. */
-            scaling_factor = 2;
-        }
-    }
-
-    if (grid->empspacing == 0) {
-        grid->scaled[NR::Y] = TRUE;
-        grid->scaled[NR::X] = TRUE;
-    }
-
-    sp_canvas_request_redraw (item->canvas,
-                     -1000000, -1000000,
-                     1000000, 1000000);
-
-    item->x1 = item->y1 = -1000000;
-    item->x2 = item->y2 = 1000000;
-}
-
-
 }; /* namespace Inkscape */
 
 /*