1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 #include "render.h"
16 #include "pointset.h"
17 
18 typedef struct {
19     Dtlink_t link;
20     point id;
21 } pair;
22 
mkPair(point p)23 static pair *mkPair(point p)
24 {
25     pair *pp;
26 
27     pp = NEW(pair);
28     pp->id = p;
29     return pp;
30 }
31 
freePair(Dt_t * d,pair * pp,Dtdisc_t * disc)32 static void freePair(Dt_t * d, pair* pp, Dtdisc_t * disc)
33 {
34     free (pp);
35 }
36 
cmppair(Dt_t * d,point * key1,point * key2,Dtdisc_t * disc)37 static int cmppair(Dt_t * d, point * key1, point * key2, Dtdisc_t * disc)
38 {
39     if (key1->x > key2->x)
40 	return 1;
41     else if (key1->x < key2->x)
42 	return -1;
43     else if (key1->y > key2->y)
44 	return 1;
45     else if (key1->y < key2->y)
46 	return -1;
47     else
48 	return 0;
49 }
50 
51 static Dtdisc_t intPairDisc = {
52     offsetof(pair, id),
53     sizeof(point),
54     offsetof(pair, link),
55     0,
56     (Dtfree_f) freePair,
57     (Dtcompar_f) cmppair,
58     0,
59     0,
60     0
61 };
62 
newPS(void)63 PointSet *newPS(void)
64 {
65     return (dtopen(&intPairDisc, Dtoset));
66 }
67 
freePS(PointSet * ps)68 void freePS(PointSet * ps)
69 {
70     dtclose(ps);
71 }
72 
insertPS(PointSet * ps,point pt)73 void insertPS(PointSet * ps, point pt)
74 {
75     pair *pp;
76 
77     pp = mkPair(pt);
78     if (dtinsert(ps, pp) != pp)
79         free(pp);
80 }
81 
addPS(PointSet * ps,int x,int y)82 void addPS(PointSet * ps, int x, int y)
83 {
84     point pt;
85     pair *pp;
86 
87     pt.x = x;
88     pt.y = y;
89     pp = mkPair(pt);
90     if (dtinsert(ps, pp) != pp)
91         free(pp);
92 }
93 
inPS(PointSet * ps,point pt)94 int inPS(PointSet * ps, point pt)
95 {
96     pair p;
97     p.id = pt;
98     return ((dtsearch(ps, &p)) ? 1 : 0);
99 }
100 
isInPS(PointSet * ps,int x,int y)101 int isInPS(PointSet * ps, int x, int y)
102 {
103     pair p;
104     p.id.x = x;
105     p.id.y = y;
106     return ((dtsearch(ps, &p)) ? 1 : 0);
107 }
108 
sizeOf(PointSet * ps)109 int sizeOf(PointSet * ps)
110 {
111     return dtsize(ps);
112 }
113 
pointsOf(PointSet * ps)114 point *pointsOf(PointSet * ps)
115 {
116     int n = dtsize(ps);
117     point *pts = N_NEW(n, point);
118     pair *p;
119     point *pp = pts;
120 
121     for (p = (pair *) dtflatten(ps); p;
122 	 p = (pair *) dtlink(ps, (Dtlink_t *) p)) {
123 	*pp++ = p->id;
124     }
125 
126     return pts;
127 }
128 
129 typedef struct {
130     Dtlink_t link;
131     point id;
132     int v;
133 } mpair;
134 
135 typedef struct {
136     Dtdisc_t disc;
137     mpair *flist;
138 } MPairDisc;
139 
mkMPair(Dt_t * d,mpair * obj,MPairDisc * disc)140 static mpair *mkMPair(Dt_t * d, mpair * obj, MPairDisc * disc)
141 {
142     mpair *ap;
143 
144     if (disc->flist) {
145 	ap = disc->flist;
146 	disc->flist = (mpair *) (ap->link.right);
147     } else
148 	ap = GNEW(mpair);
149     ap->id = obj->id;
150     ap->v = obj->v;
151     return ap;
152 }
153 
freeMPair(Dt_t * d,mpair * ap,MPairDisc * disc)154 static void freeMPair(Dt_t * d, mpair * ap, MPairDisc * disc)
155 {
156     ap->link.right = (Dtlink_t *) (disc->flist);
157     disc->flist = ap;
158 }
159 
160 static Dtdisc_t intMPairDisc = {
161     offsetof(mpair, id),
162     sizeof(point),
163     offsetof(mpair, link),
164     (Dtmake_f) mkMPair,
165     (Dtfree_f) freeMPair,
166     (Dtcompar_f) cmppair,
167     0,
168     0,
169     0
170 };
171 
newPM(void)172 PointMap *newPM(void)
173 {
174     MPairDisc *dp = GNEW(MPairDisc);
175 
176     dp->disc = intMPairDisc;
177     dp->flist = 0;
178 
179     return (dtopen(&(dp->disc), Dtoset));
180 }
181 
clearPM(PointMap * ps)182 void clearPM(PointMap * ps)
183 {
184     dtclear(ps);
185 }
186 
freePM(PointMap * ps)187 void freePM(PointMap * ps)
188 {
189     MPairDisc *dp = (MPairDisc *) (ps->disc);
190     mpair *p;
191     mpair *next;
192 
193     dtclose(ps);
194     for (p = dp->flist; p; p = next) {
195 	next = (mpair *) (p->link.right);
196 	free(p);
197     }
198     free(dp);
199 }
200 
updatePM(PointMap * pm,int x,int y,int v)201 int updatePM(PointMap * pm, int x, int y, int v)
202 {
203     mpair *p;
204     mpair dummy;
205     int old;
206 
207     dummy.id.x = x;
208     dummy.id.y = y;
209     dummy.v = v;
210     p = dtinsert(pm, &dummy);
211     old = p->v;
212     p->v = v;
213     return old;
214 }
215 
insertPM(PointMap * pm,int x,int y,int v)216 int insertPM(PointMap * pm, int x, int y, int v)
217 {
218     mpair *p;
219     mpair dummy;
220 
221     dummy.id.x = x;
222     dummy.id.y = y;
223     dummy.v = v;
224     p = dtinsert(pm, &dummy);
225     return p->v;
226 }
227