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 #include "smyrna_utils.h"
14 #include "memory.h"
15 /* many of these functions are available in libcommon.
16  * We cannot use those because dependencies cause a great
17  * deal of libcommon to be brought in, which complicates
18  * and makes possible conflicts as some parts of libcommon
19  * rely on not using libcgraph.
20  */
mapbool(char * p)21 int mapbool(char *p)
22 {
23     if (p == NULL)
24 	return FALSE;
25     if (!strcasecmp(p, "false"))
26 	return FALSE;
27     if (!strcasecmp(p, "no"))
28 	return FALSE;
29     if (!strcasecmp(p, "true"))
30 	return TRUE;
31     if (!strcasecmp(p, "yes"))
32 	return TRUE;
33     return atoi(p);
34 }
35 
36 /* return true if *s points to &[A-Za-z]*;      (e.g. Ç )
37  *                          or &#[0-9]*;        (e.g. & )
38  *                          or &#x[0-9a-fA-F]*; (e.g. 水 )
39  */
xml_isentity(char * s)40 static int xml_isentity(char *s)
41 {
42     s++;			/* already known to be '&' */
43     if (*s == '#') {
44 	s++;
45 	if (*s == 'x' || *s == 'X') {
46 	    s++;
47 	    while ((*s >= '0' && *s <= '9')
48 		   || (*s >= 'a' && *s <= 'f')
49 		   || (*s >= 'A' && *s <= 'F'))
50 		s++;
51 	} else {
52 	    while (*s >= '0' && *s <= '9')
53 		s++;
54 	}
55     } else {
56 	while ((*s >= 'a' && *s <= 'z')
57 	       || (*s >= 'A' && *s <= 'Z'))
58 	    s++;
59     }
60     if (*s == ';')
61 	return 1;
62     return 0;
63 }
64 
xml_string(char * s)65 char *xml_string(char *s)
66 {
67     static char *buf = NULL;
68     static int bufsize = 0;
69     char *p, *sub, *prev = NULL;
70     int len, pos = 0;
71 
72     if (!buf) {
73 	bufsize = 64;
74 	buf = N_NEW(bufsize, char);
75     }
76 
77     p = buf;
78     while (s && *s) {
79 	if (pos > (bufsize - 8)) {
80 	    bufsize *= 2;
81 	    buf = realloc(buf, bufsize);
82 	    p = buf + pos;
83 	}
84 	/* escape '&' only if not part of a legal entity sequence */
85 	if (*s == '&' && !(xml_isentity(s))) {
86 	    sub = "&amp;";
87 	    len = 5;
88 	}
89 	/* '<' '>' are safe to substitute even if string is already UTF-8 coded
90 	 * since UTF-8 strings won't contain '<' or '>' */
91 	else if (*s == '<') {
92 	    sub = "&lt;";
93 	    len = 4;
94 	}
95 	else if (*s == '>') {
96 	    sub = "&gt;";
97 	    len = 4;
98 	}
99 	else if (*s == '-') {	/* can't be used in xml comment strings */
100 	    sub = "&#45;";
101 	    len = 5;
102 	}
103 	else if (*s == ' ' && prev && *prev == ' ') {
104 	    /* substitute 2nd and subsequent spaces with required_spaces */
105 	    sub = "&#160;";  /* inkscape doesn't recognise &nbsp; */
106 	    len = 6;
107 	}
108 	else if (*s == '"') {
109 	    sub = "&quot;";
110 	    len = 6;
111 	}
112 	else if (*s == '\'') {
113 	    sub = "&#39;";
114 	    len = 5;
115 	}
116 	else {
117 	    sub = s;
118 	    len = 1;
119 	}
120 	while (len--) {
121 	    *p++ = *sub++;
122 	    pos++;
123 	}
124 	prev = s;
125 	s++;
126     }
127     *p = '\0';
128     return buf;
129 }
130 #if 0
131 static int late_int(void *obj,Agsym_t* attr, int def, int low)
132 {
133     char *p;
134     int rv;
135     if (attr == NULL)
136 	return def;
137     p = agxget(obj, attr);
138     if (!p || p[0] == '\0')
139 	return def;
140     if ((rv = atoi(p)) < low)
141 	rv = low;
142     return rv;
143 }
144 
145 static double late_double(void *obj, Agsym_t* attr, double def, double low)
146 {
147     char *p;
148     double rv;
149 
150     if (!attr || !obj)
151 	return def;
152     p = agxget(obj, attr);
153     if (!p || p[0] == '\0')
154 	return def;
155     if ((rv = atof(p)) < low)
156 	rv = low;
157     return rv;
158 }
159 
160 static char *late_nnstring(void *obj, Agsym_t * attr, char *def)
161 {
162     char *rv = late_string(obj, attr, def);
163     if (!rv || (rv[0] == '\0'))
164 	rv = def;
165     return rv;
166 }
167 
168 #endif
169 
late_string(void * obj,Agsym_t * attr,char * def)170 static char* late_string(void *obj, Agsym_t * attr, char *def)
171 {
172     if (!attr || !obj)
173 	return def;
174     return agxget(obj, attr);
175 }
176 
late_bool(void * obj,Agsym_t * attr,int def)177 static int late_bool(void *obj, Agsym_t * attr, int def)
178 {
179     if (attr == NULL)
180 	return def;
181     return mapbool(agxget(obj, attr));
182 }
183 
l_int(void * obj,Agsym_t * attr,int def)184 int l_int(void *obj, Agsym_t * attr, int def)
185 {
186     char *p;
187     if (attr == NULL)
188 	return def;
189     p = agxget(obj, attr);
190     if (!p || p[0] == '\0')
191 	return def;
192     return atoi(p);
193 }
194 
l_float(void * obj,Agsym_t * attr,float def)195 float l_float(void *obj, Agsym_t * attr, float def)
196 {
197     char *p;
198     if (!attr || !obj)
199 	return def;
200     p = agxget(obj, attr);
201     if (!p || p[0] == '\0')
202 	return def;
203     return atof(p);
204 }
getAttrBool(Agraph_t * g,void * obj,char * attr_name,int def)205 int getAttrBool(Agraph_t* g,void* obj,char* attr_name,int def)
206 {
207     Agsym_t* attr;
208     attr = agattr(g, AGTYPE(obj), attr_name,0);
209     return late_bool(obj, attr,def);
210 }
getAttrInt(Agraph_t * g,void * obj,char * attr_name,int def)211 int getAttrInt(Agraph_t* g,void* obj,char* attr_name,int def)
212 {
213     Agsym_t* attr;
214     attr = agattr(g, AGTYPE(obj), attr_name,0);
215     return l_int(obj,attr,def);
216 }
getAttrFloat(Agraph_t * g,void * obj,char * attr_name,float def)217 float getAttrFloat(Agraph_t* g,void* obj,char* attr_name,float def)
218 {
219     Agsym_t* attr;
220     attr = agattr(g, AGTYPE(obj), attr_name,0);
221     return l_float(obj,attr,def);
222 }
getAttrStr(Agraph_t * g,void * obj,char * attr_name,char * def)223 char* getAttrStr(Agraph_t* g,void* obj,char* attr_name,char* def)
224 {
225     Agsym_t* attr;
226     attr = agattr(g, AGTYPE(obj), attr_name,0);
227     return late_string(obj, attr,def);
228 }
229 
230 
setColor(glCompColor * c,GLfloat R,GLfloat G,GLfloat B,GLfloat A)231 void setColor(glCompColor* c,GLfloat R,GLfloat G,GLfloat B,GLfloat A)
232 {
233     c->R=R;
234     c->G=G;
235     c->B=B;
236     c->A=A;
237 }
getPointFromStr(char * str)238 glCompPoint getPointFromStr(char* str)
239 {
240 
241     glCompPoint p;
242     char* a;
243     char bf[512];
244     strcpy(bf,str);
245     p.x=0;
246     p.y=0;
247     p.z=0;
248     a=strtok(bf,",");
249     if(a)
250 	p.x=atof(a);
251     a=strtok(NULL,",");
252     if(a)
253 	p.y=atof(a);
254     a=strtok(NULL,",");
255     if(a)
256 	p.z=atof(a);
257     return p;
258 }
259 
260 
261 #if 0
262 static float interpol(float minv, float maxv, float minc, float maxc, float x)
263 {
264     return ((x - minv) * (maxc - minc) / (maxv - minv) + minc);
265 }
266 
267 
268 void
269 getcolorfromschema(colorschemaset * sc, float l, float maxl,glCompColor * c)
270 {
271     int ind;
272     float percl = l / maxl * 100.00;
273     for (ind = 0; ind < sc->schemacount; ind++) {
274 	if (percl < sc->s[ind].perc)
275 	    break;
276     }
277 
278     if (sc->s[ind].smooth) {
279 	c->R =
280 	    interpol(sc->s[ind - 1].perc, sc->s[ind].perc,
281 		     sc->s[ind - 1].c.R, sc->s[ind].c.R, percl);
282 	c->G =
283 	    interpol(sc->s[ind - 1].perc, sc->s[ind].perc,
284 		     sc->s[ind - 1].c.G, sc->s[ind].c.G, percl);
285 	c->B =
286 	    interpol(sc->s[ind - 1].perc, sc->s[ind].perc,
287 		     sc->s[ind - 1].c.B, sc->s[ind].c.B, percl);
288 	c->A = 1;
289     } else {
290 	c->R = sc->s[ind].c.R;
291 	c->G = sc->s[ind].c.G;
292 	c->B = sc->s[ind].c.B;
293 	c->A = 1;
294     }
295 }
296 #endif
297 
point_within_ellips_with_coords(float ex,float ey,float ea,float eb,float px,float py)298 int point_within_ellips_with_coords(float ex, float ey, float ea, float eb,
299 				    float px, float py)
300 {
301 
302     float dx, dy;
303     float a;
304     dx = px - ex;
305     dy = py - ey;
306     a = (dx * dx) / (ea * ea) + (dy * dy) / (eb * eb);
307     return (a <= 1);
308 }
point_within_sphere_with_coords(float x0,float y0,float z0,float r,float x,float y,float z)309 int point_within_sphere_with_coords(float x0, float y0, float z0, float r,
310 				    float x, float y, float z)
311 {
312     float rr =
313 	(x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0);
314     rr = (float) pow(rr, 0.5);
315     if (rr <= r)
316 	return 1;
317     return 0;
318 }
319 #if 0
320 float distance_to_line(float ax, float ay, float bx, float by, float cx,
321 		       float cy)
322 {
323     //this function returns the distance between a line(a-b) segment and a point(c) in 2D plane
324     return (float)
325 	sqrt(pow(((by - ay) * (cx - ax) + (bx - ax) * (cy - ay)), 2)
326 	     / (pow((bx - ax), 2) + pow((by - ay), 2))
327 	);
328 }
329 
330 int _point_in_polygon(int npol, float *xp, float *yp, float x, float y)
331 {
332     int i, j, c = 0;
333       for (i = 0, j = npol-1; i < npol; j = i++) {
334         if ((((yp[i] <= y) && (y < yp[j])) ||
335              ((yp[j] <= y) && (y < yp[i]))) &&
336             (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
337           c = !c;
338       }
339       return c;
340 }
341 #endif
342 
343 
point_in_polygon(glCompPoly * selPoly,glCompPoint p)344 int point_in_polygon(glCompPoly* selPoly,glCompPoint p)
345 {
346     int npol=selPoly->cnt;
347 
348     int i, j, c = 0;
349       for (i = 0, j = npol-1; i < npol; j = i++)
350       {
351         if ((((selPoly->pts[i].y <= p.y) && (p.y < selPoly->pts[j].y)) ||
352              ((selPoly->pts[j].y <= p.y) && (p.y < selPoly->pts[i].y))) &&
353             (p.x < (selPoly->pts[j].x - selPoly->pts[i].x) * (p.y - selPoly->pts[i].y) / (selPoly->pts[j].y - selPoly->pts[i].y) + selPoly->pts[i].x))
354           c = !c;
355       }
356       return c;
357     }
358 
359 
360