Graphviz  2.29.20120524.0446
lib/common/pointset.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 
00015 #include "render.h"
00016 #include "pointset.h"
00017 
00018 typedef struct {
00019     Dtlink_t link;
00020     point id;
00021 } pair;
00022 
00023 static pair *mkPair(point p)
00024 {
00025     pair *pp;
00026 
00027     pp = NEW(pair);
00028     pp->id = p;
00029     return pp;
00030 }
00031 
00032 static void freePair(Dt_t * d, pair* pp, Dtdisc_t * disc)
00033 {
00034     free (pp);
00035 }
00036 
00037 static int cmppair(Dt_t * d, point * key1, point * key2, Dtdisc_t * disc)
00038 {
00039     if (key1->x > key2->x)
00040         return 1;
00041     else if (key1->x < key2->x)
00042         return -1;
00043     else if (key1->y > key2->y)
00044         return 1;
00045     else if (key1->y < key2->y)
00046         return -1;
00047     else
00048         return 0;
00049 }
00050 
00051 static Dtdisc_t intPairDisc = {
00052     offsetof(pair, id),
00053     sizeof(point),
00054     offsetof(pair, link),
00055     0,
00056     (Dtfree_f) freePair,
00057     (Dtcompar_f) cmppair,
00058     0,
00059     0,
00060     0
00061 };
00062 
00063 PointSet *newPS(void)
00064 {
00065     return (dtopen(&intPairDisc, Dtoset));
00066 }
00067 
00068 void freePS(PointSet * ps)
00069 {
00070     dtclose(ps);
00071 }
00072 
00073 void insertPS(PointSet * ps, point pt)
00074 {
00075     dtinsert(ps, mkPair(pt));
00076 }
00077 
00078 void addPS(PointSet * ps, int x, int y)
00079 {
00080     point pt;
00081 
00082     pt.x = x;
00083     pt.y = y;
00084     dtinsert(ps, mkPair(pt));
00085 }
00086 
00087 int inPS(PointSet * ps, point pt)
00088 {
00089     pair p;
00090     p.id = pt;
00091     return ((dtsearch(ps, &p)) ? 1 : 0);
00092 }
00093 
00094 int isInPS(PointSet * ps, int x, int y)
00095 {
00096     pair p;
00097     p.id.x = x;
00098     p.id.y = y;
00099     return ((dtsearch(ps, &p)) ? 1 : 0);
00100 }
00101 
00102 int sizeOf(PointSet * ps)
00103 {
00104     return dtsize(ps);
00105 }
00106 
00107 point *pointsOf(PointSet * ps)
00108 {
00109     int n = dtsize(ps);
00110     point *pts = N_NEW(n, point);
00111     pair *p;
00112     point *pp = pts;
00113 
00114     for (p = (pair *) dtflatten(ps); p;
00115          p = (pair *) dtlink(ps, (Dtlink_t *) p)) {
00116         *pp++ = p->id;
00117     }
00118 
00119     return pts;
00120 }
00121 
00122 typedef struct {
00123     Dtlink_t link;
00124     point id;
00125     int v;
00126 } mpair;
00127 
00128 typedef struct {
00129     Dtdisc_t disc;
00130     mpair *flist;
00131 } MPairDisc;
00132 
00133 static mpair *mkMPair(Dt_t * d, mpair * obj, MPairDisc * disc)
00134 {
00135     mpair *ap;
00136 
00137     if (disc->flist) {
00138         ap = disc->flist;
00139         disc->flist = (mpair *) (ap->link.right);
00140     } else
00141         ap = GNEW(mpair);
00142     ap->id = obj->id;
00143     ap->v = obj->v;
00144     return ap;
00145 }
00146 
00147 static void freeMPair(Dt_t * d, mpair * ap, MPairDisc * disc)
00148 {
00149     ap->link.right = (Dtlink_t *) (disc->flist);
00150     disc->flist = ap;
00151 }
00152 
00153 static Dtdisc_t intMPairDisc = {
00154     offsetof(mpair, id),
00155     sizeof(point),
00156     offsetof(mpair, link),
00157     (Dtmake_f) mkMPair,
00158     (Dtfree_f) freeMPair,
00159     (Dtcompar_f) cmppair,
00160     0,
00161     0,
00162     0
00163 };
00164 
00165 PointMap *newPM(void)
00166 {
00167     MPairDisc *dp = GNEW(MPairDisc);
00168 
00169     dp->disc = intMPairDisc;
00170     dp->flist = 0;
00171 
00172     return (dtopen(&(dp->disc), Dtoset));
00173 }
00174 
00175 void clearPM(PointMap * ps)
00176 {
00177     dtclear(ps);
00178 }
00179 
00180 void freePM(PointMap * ps)
00181 {
00182     MPairDisc *dp = (MPairDisc *) (ps->disc);
00183     mpair *p;
00184     mpair *next;
00185 
00186     dtclose(ps);
00187     for (p = dp->flist; p; p = next) {
00188         next = (mpair *) (p->link.right);
00189         free(p);
00190     }
00191     free(dp);
00192 }
00193 
00194 int updatePM(PointMap * pm, int x, int y, int v)
00195 {
00196     mpair *p;
00197     mpair dummy;
00198     int old;
00199 
00200     dummy.id.x = x;
00201     dummy.id.y = y;
00202     dummy.v = v;
00203     p = dtinsert(pm, &dummy);
00204     old = p->v;
00205     p->v = v;
00206     return old;
00207 }
00208 
00209 int insertPM(PointMap * pm, int x, int y, int v)
00210 {
00211     mpair *p;
00212     mpair dummy;
00213 
00214     dummy.id.x = x;
00215     dummy.id.y = y;
00216     dummy.v = v;
00217     p = dtinsert(pm, &dummy);
00218     return p->v;
00219 }