Code

Fixed crash when draw height was zero.
[inkscape.git] / src / libavoid / shape.cpp
index 43195080183e19c5a1365f9a51b7509e95ef5a1c..2b241b7283e255db6dd30e15e8b9f1cacbd18f16 100644 (file)
@@ -2,7 +2,7 @@
  * vim: ts=4 sw=4 et tw=0 wm=0
  *
  * libavoid - Fast, Incremental, Object-avoiding Line Router
- * Copyright (C) 2004-2005  Michael Wybrow <mjwybrow@users.sourceforge.net>
+ * Copyright (C) 2004-2006  Michael Wybrow <mjwybrow@users.sourceforge.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * 
 */
 
+#include <cassert>
 
+#include "libavoid/shape.h"
 #include "libavoid/graph.h"  // For alertConns
+#include "libavoid/vertices.h"
 #include "libavoid/polyutil.h"
+#include "libavoid/router.h"
 
 
 namespace Avoid {
 
 
-ShapeRefList shapeRefs;
-
-
-ShapeRef::ShapeRef(unsigned int id, Polygn& ply)
-    : _id(id)
+ShapeRef::ShapeRef(Router *router, unsigned int id, Polygn& ply)
+    : _router(router)
+    , _id(id)
     , _poly(copyPoly(ply))
     , _active(false)
+    , _inMoveList(false)
     , _firstVert(NULL)
     , _lastVert(NULL)
 {
@@ -45,7 +48,7 @@ ShapeRef::ShapeRef(unsigned int id, Polygn& ply)
     VertInf *node = NULL;
     for (int pt_i = 0; pt_i < _poly.pn; pt_i++)
     {
-        node = new VertInf(i, _poly.ps[pt_i]);
+        node = new VertInf(_router, i, _poly.ps[pt_i]);
 
         if (!_firstVert)
         {
@@ -58,18 +61,15 @@ ShapeRef::ShapeRef(unsigned int id, Polygn& ply)
             //node->lstPrev = last;
             //last->lstNext = node;
         }
-        vertices.addVertex(node);
         
         last = node;
         i++;
-        // Increase total vertices count ++;
     }
     _lastVert = node;
     
     _lastVert->shNext = _firstVert;
     _firstVert->shPrev = _lastVert;
     
-    // Increase total shape count ++;
     makeActive();
 }
 
@@ -78,23 +78,45 @@ ShapeRef::~ShapeRef()
 {
     assert(_firstVert != NULL);
     
+    makeInactive();
+
     VertInf *it = _firstVert;
     do
     {
         VertInf *tmp = it;
         it = it->shNext;
 
-        // XXX: This could possibly be done less
-        //      safely but faster, all at once.
-        vertices.removeVertex(tmp);
         delete tmp;
     }
     while (it != _firstVert);
     _firstVert = _lastVert = NULL;
 
     freePoly(_poly);
+}
+
+
+void ShapeRef::setNewPoly(Polygn& poly)
+{
+    assert(_firstVert != NULL);
+    assert(_poly.pn == poly.pn);
     
-    makeInactive();
+    VertInf *curr = _firstVert;
+    for (int pt_i = 0; pt_i < _poly.pn; pt_i++)
+    {
+        assert(curr->visListSize == 0);
+        assert(curr->invisListSize == 0);
+
+        // Reset with the new polygon point.
+        curr->Reset(poly.ps[pt_i]);
+        curr->pathNext = NULL;
+        curr->pathDist = 0;
+        
+        curr = curr->shNext;
+    }
+    assert(curr == _firstVert);
+        
+    freePoly(_poly);
+    _poly = copyPoly(poly);
 }
 
 
@@ -103,7 +125,19 @@ void ShapeRef::makeActive(void)
     assert(!_active);
     
     // Add to connRefs list.
-    _pos = shapeRefs.insert(shapeRefs.begin(), this);
+    _pos = _router->shapeRefs.insert(_router->shapeRefs.begin(), this);
+
+    // Add points to vertex list.
+    VertInf *it = _firstVert;
+    do
+    {
+        VertInf *tmp = it;
+        it = it->shNext;
+
+        _router->vertices.addVertex(tmp);
+    }
+    while (it != _firstVert);
+    
     _active = true;
 }
 
@@ -113,7 +147,19 @@ void ShapeRef::makeInactive(void)
     assert(_active);
     
     // Remove from connRefs list.
-    shapeRefs.erase(_pos);
+    _router->shapeRefs.erase(_pos);
+
+    // Remove points from vertex list.
+    VertInf *it = _firstVert;
+    do
+    {
+        VertInf *tmp = it;
+        it = it->shNext;
+
+        _router->vertices.removeVertex(tmp);
+    }
+    while (it != _firstVert);
+    
     _active = false;
 }
     
@@ -142,6 +188,32 @@ Polygn ShapeRef::poly(void)
 }
 
 
+Router *ShapeRef::router(void)
+{
+    return _router;
+}
+
+
+void ShapeRef::boundingBox(BBox& bbox)
+{
+    assert(_poly.pn > 0);
+
+    bbox.a = bbox.b = _poly.ps[0];
+    Point& a = bbox.a;
+    Point& b = bbox.b;
+
+    for (int i = 1; i < _poly.pn; ++i)
+    {
+        const Point& p = _poly.ps[i];
+
+        a.x = (p.x < a.x) ? p.x : a.x;
+        a.y = (p.y < a.y) ? p.y : a.y;
+        b.x = (p.x > b.x) ? p.x : b.x;
+        b.y = (p.y > b.y) ? p.y : b.y;
+    }
+}
+
+
 void ShapeRef::removeFromGraph(void)
 {
     for (VertInf *iter = firstVert(); iter != lastVert()->lstNext; )
@@ -171,6 +243,43 @@ void ShapeRef::removeFromGraph(void)
 }
 
 
+void ShapeRef::markForMove(void)
+{
+    if (!_inMoveList)
+    {
+        _inMoveList = true;
+    }
+    else
+    {
+        fprintf(stderr, "WARNING: two moves queued for same shape prior to "
+                "rerouting.\n         This is not safe.\n");
+    }
+}
+
+
+void ShapeRef::clearMoveMark(void)
+{
+    _inMoveList = false;
+}
+
+
+VertInf *ShapeRef::getPointVertex(const Point& point)
+{
+    VertInf *curr = _firstVert;
+    do
+    {
+        if (curr->point == point)
+        {
+            return curr;
+        }
+        curr = curr->shNext;
+    }
+    while (curr != _firstVert);
+
+    return NULL;
+}
+
+
 }