Code

Fixing scrollbar size for embeded color swatches.
[inkscape.git] / src / libavoid / shape.cpp
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libavoid - Fast, Incremental, Object-avoiding Line Router
5  * Copyright (C) 2004-2006  Michael Wybrow <mjwybrow@users.sourceforge.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21 */
23 #include <cassert>
25 #include "libavoid/shape.h"
26 #include "libavoid/graph.h"  // For alertConns
27 #include "libavoid/vertices.h"
28 #include "libavoid/polyutil.h"
29 #include "libavoid/router.h"
32 namespace Avoid {
35 ShapeRef::ShapeRef(Router *router, unsigned int id, Polygn& ply)
36     : _router(router)
37     , _id(id)
38     , _poly(copyPoly(ply))
39     , _active(false)
40     , _firstVert(NULL)
41     , _lastVert(NULL)
42 {
43     bool isShape = true;
44     VertID i = VertID(id, isShape, 0);
45     
46     VertInf *last = NULL;
47     VertInf *node = NULL;
48     for (int pt_i = 0; pt_i < _poly.pn; pt_i++)
49     {
50         node = new VertInf(_router, i, _poly.ps[pt_i]);
52         if (!_firstVert)
53         {
54             _firstVert = node;
55         }
56         else
57         {
58             node->shPrev = last;
59             last->shNext = node;
60             //node->lstPrev = last;
61             //last->lstNext = node;
62         }
63         _router->vertices.addVertex(node);
64         
65         last = node;
66         i++;
67         // Increase total vertices count ++;
68     }
69     _lastVert = node;
70     
71     _lastVert->shNext = _firstVert;
72     _firstVert->shPrev = _lastVert;
73     
74     // Increase total shape count ++;
75     makeActive();
76 }
79 ShapeRef::~ShapeRef()
80 {
81     assert(_firstVert != NULL);
82     
83     VertInf *it = _firstVert;
84     do
85     {
86         VertInf *tmp = it;
87         it = it->shNext;
89         // XXX: This could possibly be done less
90         //      safely but faster, all at once.
91         _router->vertices.removeVertex(tmp);
92         delete tmp;
93     }
94     while (it != _firstVert);
95     _firstVert = _lastVert = NULL;
97     freePoly(_poly);
98     
99     makeInactive();
103 void ShapeRef::makeActive(void)
105     assert(!_active);
106     
107     // Add to connRefs list.
108     _pos = _router->shapeRefs.insert(_router->shapeRefs.begin(), this);
109     _active = true;
113 void ShapeRef::makeInactive(void)
115     assert(_active);
116     
117     // Remove from connRefs list.
118     _router->shapeRefs.erase(_pos);
119     _active = false;
121     
123 VertInf *ShapeRef::firstVert(void)
125     return _firstVert;
129 VertInf *ShapeRef::lastVert(void)
131     return _lastVert;
135 unsigned int ShapeRef::id(void)
137     return _id;
141 Polygn ShapeRef::poly(void)
143     return _poly;
147 Router *ShapeRef::router(void)
149     return _router;
153 void ShapeRef::boundingBox(BBox& bbox)
155     assert(_poly.pn > 0);
157     bbox.a = bbox.b = _poly.ps[0];
158     Point& a = bbox.a;
159     Point& b = bbox.b;
161     for (int i = 1; i < _poly.pn; ++i)
162     {
163         const Point& p = _poly.ps[i];
165         a.x = (p.x < a.x) ? p.x : a.x;
166         a.y = (p.y < a.y) ? p.y : a.y;
167         b.x = (p.x > b.x) ? p.x : b.x;
168         b.y = (p.y > b.y) ? p.y : b.y;
169     }
173 void ShapeRef::removeFromGraph(void)
175     for (VertInf *iter = firstVert(); iter != lastVert()->lstNext; )
176     {
177         VertInf *tmp = iter;
178         iter = iter->lstNext;
179         
180         // For each vertex.
181         EdgeInfList& visList = tmp->visList;
182         EdgeInfList::iterator finish = visList.end();
183         EdgeInfList::iterator edge;
184         while ((edge = visList.begin()) != finish)
185         {
186             // Remove each visibility edge
187             (*edge)->alertConns();
188             delete (*edge);
189         }
191         EdgeInfList& invisList = tmp->invisList;
192         finish = invisList.end();
193         while ((edge = invisList.begin()) != finish)
194         {
195             // Remove each invisibility edge
196             delete (*edge);
197         }
198     }