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 = "&";
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 = "<";
93 len = 4;
94 }
95 else if (*s == '>') {
96 sub = ">";
97 len = 4;
98 }
99 else if (*s == '-') { /* can't be used in xml comment strings */
100 sub = "-";
101 len = 5;
102 }
103 else if (*s == ' ' && prev && *prev == ' ') {
104 /* substitute 2nd and subsequent spaces with required_spaces */
105 sub = " "; /* inkscape doesn't recognise */
106 len = 6;
107 }
108 else if (*s == '"') {
109 sub = """;
110 len = 6;
111 }
112 else if (*s == '\'') {
113 sub = "'";
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