--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#ifdef WIN32
+#include <pango/pangocairo.h>
+#else
+#define PANGO_ENABLE_BACKEND
+#include <pango/pangocairo.h>
+#include <pango/pango-utils.h>
+#endif
+const char* testPango()
+{
+ return pango_version_string ();
+}
+
+void drawText (char* text,char* fontName,int fontSize,float x,float y)
+{
+ PangoContext* p_context;
+ GList* pangoItems;
+ PangoAttrList *attrs;
+ p_context=pango_context_new();
+
+ pangoItems=pango_itemize(p_context,"hello world",0,10,attrs,NULL);
+ g_object_unref(p_context);
+
+}
+
+
+
+
+
+
--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#ifndef OPENGL_PANGO_H
+#define OPENGL_PANGO_H
+
+//</PANGO>
+
+
+
+#endif
--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+/* cc `pkg-config --cflags --libs pangocairo libpng12` pangotest.c -o pangotest */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <pango/pangocairo.h>
+
+#define DEFAULT_FONT_FAMILY "Arial"
+#define DEFAULT_FONT_SIZE 32
+#define ANTIALIAS
+
+
+
+static void
+die (const char *gasp)
+{
+ fprintf (stderr, "Error: %s\n", gasp);
+ exit (1);
+}
+
+
+
+PangoLayout * get_pango_layout (cairo_t *cr,
+ char *markup_text,
+ double *width,
+ double *height)
+{
+ PangoFontDescription *desc;
+ PangoFontMap* fontmap;
+ PangoContext *context;
+ PangoLayout *layout;
+ int pango_width, pango_height;
+ char *text;
+ PangoAttrList *attr_list;
+ cairo_font_options_t* options;
+ fontmap = pango_cairo_font_map_get_default();
+ context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(fontmap));
+ options=cairo_font_options_create();
+#ifdef ANTIALIAS
+// cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
+#endif
+ cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
+ cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
+ cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
+// pango_cairo_context_set_font_options(context, options);
+
+ desc = pango_font_description_new();
+ pango_font_description_set_family(desc, "CENTAUR.TTF");
+ pango_font_description_set_size (desc, DEFAULT_FONT_SIZE * PANGO_SCALE);
+// pango_font_description_set_style (desc,PANGO_STYLE_ITALIC);
+
+ if (! pango_parse_markup (markup_text, -1, '\0', &attr_list, &text, NULL, NULL))
+ die("pango_parse_markup");
+ layout = pango_layout_new (context);
+ pango_layout_set_text (layout, text, -1);
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_attributes (layout, attr_list);
+ pango_font_description_free (desc);
+
+ if (width || height)
+ pango_layout_get_size (layout, &pango_width, &pango_height);
+
+ if (width)
+ *width = (double) pango_width / PANGO_SCALE;
+
+ if (height)
+ *height = (double) pango_height / PANGO_SCALE;
+
+ return layout;
+}
+
+cairo_status_t
+writer (void *closure, const unsigned char *data, unsigned int length)
+{
+ int a;
+ if (length == fwrite(data, 1, length, (FILE *)closure))
+ {
+ return CAIRO_STATUS_SUCCESS;
+
+ }
+
+ return CAIRO_STATUS_WRITE_ERROR;
+}
+
+int
+pango_main(char* filename)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ PangoLayout *layout;
+ double width, height;
+ FILE* output_file;
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,1400,60);
+ cr = cairo_create(surface);
+ cairo_rectangle(cr, 0, 0, 1400, 60);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_fill(cr);
+ cairo_set_source_rgb(cr, 0, 0, 0);
+
+
+ layout = get_pango_layout (cr,"ABCDEFGHIJKLMNOPRSTUVYZ.abcdefghijklmnoprstuvsd", &width, &height);
+ pango_cairo_show_layout(cr, layout);
+ output_file = fopen(filename, "wb+");
+ cairo_surface_write_to_png_stream(surface, writer, output_file);
+ g_object_unref (layout);
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ fclose(output_file);
+ return 0;
+}
--- /dev/null
+
+
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regex.h 8.2 (Berkeley) 1/3/94
+ */
+
+#ifndef _REGEX_H_
+#define _REGEX_H_
+
+#ifdef WIN32
+#include <sys/types.h>
+#define __const
+#define __BEGIN_DECLS
+#define __END_DECLS
+#define __P(_X) _X
+#else
+#include <sys/cdefs.h>
+#define __stdcall
+#endif
+
+/* types */
+typedef off_t regoff_t;
+
+typedef struct {
+ int re_magic;
+ size_t re_nsub; /* number of parenthesized subexpressions */
+ __const char *re_endp; /* end pointer for REG_PEND */
+ struct re_guts *re_g; /* none of your business :-) */
+} regex_t;
+
+typedef struct {
+ regoff_t rm_so; /* start of match */
+ regoff_t rm_eo; /* end of match */
+} regmatch_t;
+
+/* regcomp() flags */
+#define REG_BASIC 0000
+#define REG_EXTENDED 0001
+#define REG_ICASE 0002
+#define REG_NOSUB 0004
+#define REG_NEWLINE 0010
+#define REG_NOSPEC 0020
+#define REG_PEND 0040
+#define REG_DUMP 0200
+
+/* regerror() flags */
+#define REG_NOMATCH 1
+#define REG_BADPAT 2
+#define REG_ECOLLATE 3
+#define REG_ECTYPE 4
+#define REG_EESCAPE 5
+#define REG_ESUBREG 6
+#define REG_EBRACK 7
+#define REG_EPAREN 8
+#define REG_EBRACE 9
+#define REG_BADBR 10
+#define REG_ERANGE 11
+#define REG_ESPACE 12
+#define REG_BADRPT 13
+#define REG_EMPTY 14
+#define REG_ASSERT 15
+#define REG_INVARG 16
+#define REG_ATOI 255 /* convert name to number (!) */
+#define REG_ITOA 0400 /* convert number to name (!) */
+
+/* regexec() flags */
+#define REG_NOTBOL 00001
+#define REG_NOTEOL 00002
+#define REG_STARTEND 00004
+#define REG_TRACE 00400 /* tracing of execution */
+#define REG_LARGE 01000 /* force large representation */
+#define REG_BACKR 02000 /* force use of backref code */
+
+__BEGIN_DECLS
+int __stdcall regcomp __P((regex_t *, const char *, int));
+size_t __stdcall regerror __P((int, const regex_t *, char *, size_t));
+int __stdcall regexec __P((const regex_t *,
+ const char *, size_t, regmatch_t [], int));
+void __stdcall regfree __P((regex_t *));
+__END_DECLS
+
+#endif /* !_REGEX_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regex2.h 8.4 (Berkeley) 3/20/94
+ */
+
+/*
+ * First, the stuff that ends up in the outside-world include file
+ = typedef off_t regoff_t;
+ = typedef struct {
+ = int re_magic;
+ = size_t re_nsub; // number of parenthesized subexpressions
+ = const char *re_endp; // end pointer for REG_PEND
+ = struct re_guts *re_g; // none of your business :-)
+ = } regex_t;
+ = typedef struct {
+ = regoff_t rm_so; // start of match
+ = regoff_t rm_eo; // end of match
+ = } regmatch_t;
+ */
+/*
+ * internals of regex_t
+ */
+#define MAGIC1 ((('r'^0200)<<8) | 'e')
+
+/*
+ * The internal representation is a *strip*, a sequence of
+ * operators ending with an endmarker. (Some terminology etc. is a
+ * historical relic of earlier versions which used multiple strips.)
+ * Certain oddities in the representation are there to permit running
+ * the machinery backwards; in particular, any deviation from sequential
+ * flow must be marked at both its source and its destination. Some
+ * fine points:
+ *
+ * - OPLUS_ and O_PLUS are *inside* the loop they create.
+ * - OQUEST_ and O_QUEST are *outside* the bypass they create.
+ * - OCH_ and O_CH are *outside* the multi-way branch they create, while
+ * OOR1 and OOR2 are respectively the end and the beginning of one of
+ * the branches. Note that there is an implicit OOR2 following OCH_
+ * and an implicit OOR1 preceding O_CH.
+ *
+ * In state representations, an operator's bit is on to signify a state
+ * immediately *preceding* "execution" of that operator.
+ */
+typedef unsigned long sop; /* strip operator */
+typedef long sopno;
+#define OPRMASK 0xf8000000
+#define OPDMASK 0x07ffffff
+#define OPSHIFT ((unsigned)27)
+#define OP(n) ((n)&OPRMASK)
+#define OPND(n) ((n)&OPDMASK)
+#define SOP(op, opnd) ((op)|(opnd))
+/* operators meaning operand */
+/* (back, fwd are offsets) */
+#define OEND (1<<OPSHIFT) /* endmarker - */
+#define OCHAR (2<<OPSHIFT) /* character unsigned char */
+#define OBOL (3<<OPSHIFT) /* left anchor - */
+#define OEOL (4<<OPSHIFT) /* right anchor - */
+#define OANY (5<<OPSHIFT) /* . - */
+#define OANYOF (6<<OPSHIFT) /* [...] set number */
+#define OBACK_ (7<<OPSHIFT) /* begin \d paren number */
+#define O_BACK (8<<OPSHIFT) /* end \d paren number */
+#define OPLUS_ (9<<OPSHIFT) /* + prefix fwd to suffix */
+#define O_PLUS (10<<OPSHIFT) /* + suffix back to prefix */
+#define OQUEST_ (11<<OPSHIFT) /* ? prefix fwd to suffix */
+#define O_QUEST (12<<OPSHIFT) /* ? suffix back to prefix */
+#define OLPAREN (13<<OPSHIFT) /* ( fwd to ) */
+#define ORPAREN (14<<OPSHIFT) /* ) back to ( */
+#define OCH_ (15<<OPSHIFT) /* begin choice fwd to OOR2 */
+#define OOR1 (16<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */
+#define OOR2 (17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */
+#define O_CH (18<<OPSHIFT) /* end choice back to OOR1 */
+#define OBOW (19<<OPSHIFT) /* begin word - */
+#define OEOW (20<<OPSHIFT) /* end word - */
+
+/*
+ * Structure for [] character-set representation. Character sets are
+ * done as bit vectors, grouped 8 to a byte vector for compactness.
+ * The individual set therefore has both a pointer to the byte vector
+ * and a mask to pick out the relevant bit of each byte. A hash code
+ * simplifies testing whether two sets could be identical.
+ *
+ * This will get trickier for multicharacter collating elements. As
+ * preliminary hooks for dealing with such things, we also carry along
+ * a string of multi-character elements, and decide the size of the
+ * vectors at run time.
+ */
+typedef struct {
+ uch *ptr; /* -> uch [csetsize] */
+ uch mask; /* bit within array */
+ uch hash; /* hash code */
+ size_t smultis;
+ char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
+} cset;
+/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
+#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
+#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
+#define MCsub(p, cs, cp) mcsub(p, cs, cp)
+#define MCin(p, cs, cp) mcin(p, cs, cp)
+
+/* stuff for character categories */
+typedef unsigned char cat_t;
+
+/*
+ * main compiled-expression structure
+ */
+struct re_guts {
+ int magic;
+# define MAGIC2 ((('R'^0200)<<8)|'E')
+ sop *strip; /* malloced area for strip */
+ int csetsize; /* number of bits in a cset vector */
+ int ncsets; /* number of csets in use */
+ cset *sets; /* -> cset [ncsets] */
+ uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
+ int cflags; /* copy of regcomp() cflags argument */
+ sopno nstates; /* = number of sops */
+ sopno firststate; /* the initial OEND (normally 0) */
+ sopno laststate; /* the final OEND */
+ int iflags; /* internal flags */
+# define USEBOL 01 /* used ^ */
+# define USEEOL 02 /* used $ */
+# define BAD 04 /* something wrong */
+ int nbol; /* number of ^ used */
+ int neol; /* number of $ used */
+ int ncategories; /* how many character categories */
+ cat_t *categories; /* ->catspace[-CHAR_MIN] */
+ char *must; /* match must contain this string */
+ int mlen; /* length of must */
+ size_t nsub; /* copy of re_nsub */
+ int backrefs; /* does it use back references? */
+ sopno nplus; /* how deep does it nest +s? */
+ /* catspace must be last */
+ cat_t catspace[1]; /* actually [NC] */
+};
+
+/* misc utilities */
+#define OUT (CHAR_MAX+1) /* a non-character value */
+#define ISWORD(c) (isalnum(c) || (c) == '_')
--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#include "selection.h"
+int rectintersects(float x,float y,float W,float H)
+{
+ //returns 1 if rect is completely in the clip rect
+ //0 if they intersect
+ //-1 if completely out
+
+ int s[4];
+ s[0]=( ((x >=view.Selection.X)&& (x <= (view.Selection.X + view.Selection.W) ))) ? 1:0;
+ s[1]=( (((x+W) >=view.Selection.X)&& ((x+W) <= (view.Selection.X + view.Selection.W) ))) ? 1:0;
+
+ s[2]=( ((y >=view.Selection.Y)&& (y <= (view.Selection.Y + view.Selection.H) ))) ? 1:0;
+ s[3]=( (((y+H) >=view.Selection.Y)&& ((y+H) <= (view.Selection.Y + view.Selection.H) ))) ? 1:0;
+
+
+ if (s[0] && s[1] && s[2] && s[3])
+ return 1;
+ if (s[0] || s[1] || s[2] || s[3])
+ return 0;
+ return -1;
+
+}
+int lineintersects(float X1,float X2,float Y1,float Y2)
+{
+ //line segment
+ //X1,Y1 point 1
+ //X2,Y3 point 2
+ //rectangle
+ //RX,RY lower left corner of rectangle
+ //RW width of rectangle
+ //RH height of ractangle
+ //returns 1 if line segment is completely in the rect
+ //0 if they intersect
+ //-1 if completely out
+ float x,y,m,iter;
+ float RX,RY,RW,RH;
+ int intersects,in;
+ RX=view.Selection.X;
+ RY=view.Selection.Y;
+ RW=view.Selection.W;
+ RH=view.Selection.H;
+ if((is_point_in_rectangle(X1,Y1,RX,RY,RW,RH)) && (is_point_in_rectangle(X2,Y2,RX,RY,RW,RH)))
+ return 1;
+ if((is_point_in_rectangle(X1,Y1,RX,RY,RW,RH)) || (is_point_in_rectangle(X2,Y2,RX,RY,RW,RH)))
+ return 0;
+ //to be absolute or not to be one
+ if(X1 > X2)
+ {
+ x=X2;
+ y=Y2;
+ X2=X1;
+ Y2=Y1;
+ X1=x;
+ Y1=y;
+ }
+ x=X1;
+ //iter
+ iter=RW/SELECTION_SEGMENT_DIVIDER;
+ m=(Y2-Y1)/(X2-X1);
+
+ in=1;
+ intersects=0;
+ while (x <= X2)
+ {
+ x=x+iter;
+ y=Y1+m*(x-X1);
+ if ( !is_point_in_rectangle(x,y,RX,RY,RW,RH))
+ in=0;
+ else
+ intersects=1;
+
+ }
+ if (in==1)
+ return 1;
+ if (intersects==1)
+ return 0;
+ return -1;
+}
+int is_point_in_rectangle(float X,float Y,float RX,float RY,float RW,float RH)
+{
+ if ((X >= RX) && (X <= (RX+RW) ) && (Y >= RY) && (Y <= (RY+RH)))
+ return 1;
+ else
+ return 0;
+
+
+}
+
+int SelectBeziers(xdot_op* op)
+{
+ if(!view.Selection.Active)
+ return 0;
+ switch (view.Selection.Type)
+ {
+ case 0:
+ if (view.Selection.AlreadySelected)
+ return 0;
+ if( spline_x_rect(op))
+ {
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ }
+ }
+ break;
+ case 1:
+// if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+// return 0;
+ if( ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag != -1 ) && (spline_in_rect(op)) )
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=1;
+// select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=0;
+// deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag = -1;
+ }
+ break;
+ case 2:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(spline_x_rect(op))
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ }
+ break;
+ default:
+ return 0;
+ }
+
+}
+
+int SelectPolygon(xdot_op* op)
+{
+
+ if(!view.Selection.Active)
+ return 0;
+ switch (view.Selection.Type)
+ {
+ case 0:
+ if (view.Selection.AlreadySelected)
+ return 0;
+
+
+ if ((point_within_polygon( op)) || (polygon_x_rect(op)))
+ {
+
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ }
+ break;
+ case 1:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if( ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag != -1 ) && (polygon_in_rect(op)) )
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=1;
+// select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+// view.Selection.AlreadySelected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=0;
+// deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag = -1;
+ }
+
+
+ break;
+ case 2:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(polygon_x_rect(op))
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ break;
+ default:
+ return 0;
+ }
+}
+
+int SelectPolyline(xdot_op* op)
+{
+ if(!view.Selection.Active)
+ return 0;
+ switch (view.Selection.Type)
+ {
+ case 0:
+ if (view.Selection.AlreadySelected)
+ return 0;
+
+
+ if ( polyline_x_rect(op) )
+ {
+
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ }
+ break;
+ case 1:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if( ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag != -1 ) && (polyline_in_rect(op)) )
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=0;
+ view.Selection.AlreadySelected=1;
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag = -1;
+ }
+
+
+ break;
+ case 2:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(polyline_x_rect(op))
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ break;
+ default:
+ return 0;
+ }
+
+
+
+}
+int SelectEllipse(xdot_op* op)
+{
+ if(!view.Selection.Active)
+ return 0;
+ switch (view.Selection.Type)
+ {
+ case 0:
+ if (view.Selection.AlreadySelected)
+ return 0;
+
+ if( point_within_ellipse(op))
+ {
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ }
+ else if( ellipse_x_rect(op))
+ {
+
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ deselect_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ }
+ break;
+ case 1:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if( ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag != -1 ) && (ellipse_in_rect(op)) )
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=1;
+ view.Selection.AlreadySelected=1;
+
+ }
+ else
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Preselected=0;
+ view.Selection.AlreadySelected=1;
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->selectionflag = -1;
+ }
+
+ break;
+ case 2:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(ellipse_x_rect(op))
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ break;
+ default:
+ return 0;
+ }
+}
+
+
+int SelectText(xdot_op* op)
+{
+ if(!view.Selection.Active)
+ return 0;
+ switch (view.Selection.Type)
+ {
+ case 0:
+ if (view.Selection.AlreadySelected)
+ return 0;
+ if( text_x_rect(op))
+ {
+
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ else
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ }
+ break;
+ case 1:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(text_in_rect(op))
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+
+ }
+ break;
+ case 2:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(text_x_rect(op))
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ }
+ break;
+ default:
+ return 0;
+ }
+
+
+}
+
+int SelectImage(xdot_op* op)
+{
+ if(!view.Selection.Active)
+ return 0;
+ switch (view.Selection.Type)
+ {
+ case 0:
+ if (view.Selection.AlreadySelected)
+ return 0;
+ if( image_x_rect(op))
+ {
+
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==0)
+ {
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ select_object (view.g[view.activeGraph],((xdot*)(op->parentxdot))->obj);
+ view.Selection.AlreadySelected=1;
+ }
+ else
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=0;
+ }
+ break;
+ case 1:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(image_in_rect(op))
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ break;
+ case 2:
+ if ( ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected==1)
+ return 0;
+ if(image_x_rect(op))
+ ((custom_object_data*)AGDATA(((xdot*)(op->parentxdot))->obj))->Selected=1;
+ break;
+ default:
+ return 0;
+ }
+
+
+}
+
+
+
+
+int spline_in_rect(xdot_op* op)
+{
+ //JUST SEND ALL CONTROL POINTS IN 3D ARRAYS
+ GLfloat tempX[4];
+ GLfloat tempY[4];
+ GLfloat tempZ[4];
+ int temp=0;
+ int i=0;
+ for (i=0;i < op->u.bezier.cnt ; i= i + 1)
+ {
+ if (temp==4)
+ {
+ if(!within_bezier(tempX,tempY,tempZ,0))
+ return 0;
+ tempX[0]=op->u.bezier.pts[i-1].x;
+ tempY[0]=op->u.bezier.pts[i-1].y;
+ tempZ[0]=op->u.bezier.pts[i-1].z;
+ temp=1;
+ tempX[temp]=op->u.bezier.pts[i].x;
+ tempY[temp]=op->u.bezier.pts[i].y;
+ tempZ[temp]=op->u.bezier.pts[i].z;
+ temp=temp+1;
+ }
+ else
+ {
+ tempX[temp]=op->u.bezier.pts[i].x;
+ tempY[temp]=op->u.bezier.pts[i].y;
+ tempZ[temp]=op->u.bezier.pts[i].z;
+ temp=temp+1;
+ }
+ }
+ if(!within_bezier(tempX,tempY,tempZ,0))
+ return 0;
+ else
+ return 1;
+}
+int spline_x_rect(xdot_op* op)
+{
+ //JUST SEND ALL CONTROL POINTS IN 3D ARRAYS
+ GLfloat tempX[4];
+ GLfloat tempY[4];
+ GLfloat tempZ[4];
+ int temp=0;
+ int i=0;
+ for (i=0;i < op->u.bezier.cnt ; i= i + 1)
+ {
+ if (temp==4)
+ {
+ if(within_bezier(tempX,tempY,tempZ,1))
+ return 1;
+ tempX[0]=op->u.bezier.pts[i-1].x;
+ tempY[0]=op->u.bezier.pts[i-1].y;
+ tempZ[0]=op->u.bezier.pts[i-1].z;
+ temp=1;
+ tempX[temp]=op->u.bezier.pts[i].x;
+ tempY[temp]=op->u.bezier.pts[i].y;
+ tempZ[temp]=op->u.bezier.pts[i].z;
+ temp=temp+1;
+ }
+ else
+ {
+ tempX[temp]=op->u.bezier.pts[i].x;
+ tempY[temp]=op->u.bezier.pts[i].y;
+ tempZ[temp]=op->u.bezier.pts[i].z;
+ temp=temp+1;
+ }
+ }
+ if(within_bezier(tempX,tempY,tempZ,1))
+ return 1;
+ else
+ return 0;
+}
+int polygon_in_rect(xdot_op* op)
+{
+ int ind=0;
+ for (ind=0;ind < op->u.polygon.cnt-1;ind ++)
+ {
+ if( lineintersects(op->u.polygon.pts[ind].x,op->u.polygon.pts[ind+1].x,op->u.polygon.pts[ind].y,op->u.polygon.pts[ind+1].y)!=1)
+ return 0;
+ };
+ return 1;
+}
+int polygon_x_rect(xdot_op* op)
+{
+ int ind=0;
+ for (ind=0;ind < op->u.polygon.cnt-1;ind ++)
+ {
+ if( lineintersects(op->u.polygon.pts[ind].x,op->u.polygon.pts[ind+1].x,op->u.polygon.pts[ind].y,op->u.polygon.pts[ind+1].y)>=0)
+ return 1;
+ };
+ return 0;
+}
+int polyline_in_rect(xdot_op* op)
+{
+ int ind=0;
+ for (ind=0;ind < op->u.polygon.cnt-1;ind ++)
+ {
+ if( lineintersects(op->u.polygon.pts[ind].x,op->u.polygon.pts[ind+1].x,op->u.polygon.pts[ind].y,op->u.polygon.pts[ind+1].y)!=1)
+ return 0;
+ };
+ return 1;
+}
+int polyline_x_rect(xdot_op* op)
+{
+ int ind=0;
+ for (ind=0;ind < op->u.polygon.cnt-1;ind ++)
+ {
+ if( lineintersects(op->u.polygon.pts[ind].x,op->u.polygon.pts[ind+1].x,op->u.polygon.pts[ind].y,op->u.polygon.pts[ind+1].y)>=1)
+ return 1;
+ };
+ return 0;
+}
+int text_in_rect(xdot_op* op)
+{
+ if( rectintersects(op->u.text.x,op->u.text.y,op->u.text.x+op->u.text.width,op->u.text.y+op->u.text.size)==1 )
+ return 1;
+ return 0;
+
+}
+int text_x_rect(xdot_op* op)
+{
+ if( rectintersects(op->u.text.x,op->u.text.y,op->u.text.x+op->u.text.width,op->u.text.y+op->u.text.size)>=1 )
+ return 1;
+ return 0;
+
+}
+int image_in_rect(xdot_op* op)
+{
+ if( rectintersects(op->u.image.pos.x ,op->u.image.pos.y,op->u.image.pos.w,op->u.image.pos.h)==1)
+ return 1;
+ return 0;
+}
+int image_x_rect(xdot_op* op)
+{
+ if( rectintersects(op->u.image.pos.x ,op->u.image.pos.y,op->u.image.pos.w,op->u.image.pos.h)>=0)
+ return 1;
+ return 0;
+}
+
+int within_bezier(GLfloat* xp,GLfloat* yp,GLfloat* zp,int isx)
+{
+ double Ax = xp[0]; double Ay = yp[0]; double Az = zp[0];
+ double Bx = xp[1]; double By = yp[1]; double Bz = zp[1];
+ double Cx = xp[2]; double Cy = yp[2]; double Cz = zp[2];
+ double Dx = xp[3]; double Dy = yp[3]; double Dz = zp[3];
+ double X;
+ double Y;
+ double Z;
+ double Xprev;
+ double Yprev;
+ double Zprev;
+ int i = 0;//loop index
+ // Variable
+ double a = 1.0;
+ double b = 1.0 - a;
+ int in=1;
+ int inter=0;
+ for(i = 0; i <= 20; i++)
+ {
+ // Get a point on the curve
+ X = Ax*a*a*a + Bx*3*a*a*b + Cx*3*a*b*b + Dx*b*b*b;
+ Y = Ay*a*a*a + By*3*a*a*b + Cy*3*a*b*b + Dy*b*b*b;
+ Z = Az*a*a*a + Bz*3*a*a*b + Cz*3*a*b*b + Dz*b*b*b;
+ if (i>0)
+ {
+ if(lineintersects(Xprev,X,Yprev,Y) >=0) //intersection
+ {
+ if(isx)
+ return 1;
+ }
+ if(!(lineintersects(Xprev,X,Yprev,Y)==1)) //withing the rect
+ {
+ if(!isx)
+ return 0;
+ }
+ }
+ Xprev=X;
+ Yprev=Y;
+ Zprev=Z;
+
+ a -= 0.05;
+ b = 1.0 - a;
+ }
+ if(isx)
+ return 0;
+ else
+ return 1;
+
+}
+
+
+int ellipse_x_rect(xdot_op* op)
+{
+ GLfloat x,y,xradius,yradius;
+
+ double Xprev;
+ double Yprev;
+ double Zprev;
+
+ int i=0;
+ x=op->u.ellipse.x;
+ y=op->u.ellipse.y;
+ xradius=(GLfloat)op->u.ellipse.w;
+ yradius=(GLfloat)op->u.ellipse.h;
+ for (i=0; i < 360; i=i+1)
+ {
+ //convert degrees into radians
+ float degInRad = i*DEG2RAD;
+ if (i>0)
+ {
+ if(lineintersects(Xprev,x+cos(degInRad)*xradius,Yprev,y+sin(degInRad)*yradius) >=0) //intersection
+ return 1;
+ }
+
+ Xprev=x+cos(degInRad)*xradius;
+ Yprev=y+sin(degInRad)*yradius;
+ Zprev=0;
+ }
+ return 0;
+}
+
+int ellipse_in_rect(xdot_op* op)
+{
+ GLfloat x,y,xradius,yradius;
+
+ double Xprev;
+ double Yprev;
+ double Zprev;
+
+ int i=0;
+ x=op->u.ellipse.x;
+ y=op->u.ellipse.y;
+ xradius=(GLfloat)op->u.ellipse.w;
+ yradius=(GLfloat)op->u.ellipse.h;
+ for (i=0; i < 360; i=i+1)
+ {
+ //convert degrees into radians
+ float degInRad = i*DEG2RAD;
+ if (i>0)
+ {
+ if(!(lineintersects(Xprev,x+cos(degInRad)*xradius,Yprev,y+sin(degInRad)*yradius)==1)) //withing the rect
+ return 0;
+ }
+
+ Xprev=x+cos(degInRad)*xradius;
+ Yprev=y+sin(degInRad)*yradius;
+ Zprev=0;
+ }
+ return 1;
+}
+
+int point_within_ellipse( xdot_op* op)
+{
+
+ float dx,dy,ex,ey,ea,eb,px,py ;
+ float a;
+
+ ex=op->u.ellipse.x;
+ ey=op->u.ellipse.y;
+ ea=op->u.ellipse.w;
+ eb=op->u.ellipse.h;
+ px=view.Selection.X+SINGLE_SELECTION_WIDTH/2;
+ py=view.Selection.Y+SINGLE_SELECTION_WIDTH/2;
+ dx = px - ex;
+ dy = py - ey;
+ a=(dx*dx)/(ea*ea) + (dy*dy)/(eb*eb);
+ return (a <= 1);
+}
+
+int point_within_polygon(xdot_op* op)
+//int pnpoly(int npol, float *xp, float *yp, float x, float y)
+{
+ int i, j, c = 0;
+ int npol=op->u.polygon.cnt;
+ float x,y;
+ op->u.polygon.pts[i].y;
+ op->u.polygon.pts[i].x;
+ x=view.Selection.X+SINGLE_SELECTION_WIDTH/2;
+ y=view.Selection.Y+SINGLE_SELECTION_WIDTH/2;
+
+ for (i = 0, j = npol-1; i < npol; j = i++) {
+
+
+ if ((((op->u.polygon.pts[i].y <= y) && (y < op->u.polygon.pts[j].y)) ||
+ ((op->u.polygon.pts[j].y <= y) && (y < op->u.polygon.pts[i].y))) &&
+ (x < (op->u.polygon.pts[j].x - op->u.polygon.pts[i].x) * (y - op->u.polygon.pts[i].y) / (op->u.polygon.pts[j].y - op->u.polygon.pts[i].y) + op->u.polygon.pts[i].x))
+ c = !c;
+ }
+ return c;
+}
+
+
+//select functions
+int select_node(Agraph_t* g,Agnode_t* N)
+{
+ int ind=0;
+ //check if in the list
+ for (ind=0;ind < ((custom_graph_data*)AGDATA(g))->selectedNodesCount ; ind ++ )
+ {
+ if( ((custom_graph_data*)AGDATA(g))->selectedNodes[ind] == N)
+ return 0;
+ }
+ //for single selections i think realloc is ok, for mass selections i ll figure out something else
+ ((custom_graph_data*)AGDATA(g))->selectedNodes=realloc(((custom_graph_data*)AGDATA(g))->selectedNodes,sizeof(Agnode_t*)*(((custom_graph_data*)AGDATA(g))->selectedNodesCount+1));
+ ((custom_graph_data*)AGDATA(g))->selectedNodes[((custom_graph_data*)AGDATA(g))->selectedNodesCount]=N;
+ ((custom_graph_data*)AGDATA(g))->selectedNodesCount++;
+ ((custom_object_data*)AGDATA(N))->Selected=1;
+ printf("Node Selecteed \n");
+}
+int select_edge(Agraph_t* g,Agedge_t* E)
+{
+ int ind=0;
+ //check if in the list
+ for (ind=0;ind < ((custom_graph_data*)AGDATA(g))->selectedEdgesCount ; ind ++ )
+ {
+ if(((custom_graph_data*)AGDATA(g))->selectedEdges[ind] == E)
+ return 0;
+ }
+ //for single selections i think realloc is ok, for mass selections i ll figure out something else
+ ((custom_graph_data*)AGDATA(g))->selectedEdges=realloc(((custom_graph_data*)AGDATA(g))->selectedEdges,sizeof(Agnode_t*)*(((custom_graph_data*)AGDATA(g))->selectedEdgesCount+1));
+ ((custom_graph_data*)AGDATA(g))->selectedEdges[((custom_graph_data*)AGDATA(g))->selectedEdgesCount]=E;
+ ((custom_graph_data*)AGDATA(g))->selectedEdgesCount++;
+ ((custom_object_data*)AGDATA(E))->Selected=1;
+
+}
+int select_object (Agraph_t* g,void* obj)
+{
+ switch(AGTYPE(obj))
+ {
+ case AGNODE:
+ select_node(g,obj);
+ break;
+ case AGEDGE:
+ select_edge(g,obj);
+ break;
+ case AGRAPH:
+ select_graph(g,obj);
+ break;
+ default:
+ break;
+ }
+}
+int deselect_object (Agraph_t* g,void* obj)
+{
+ switch(AGTYPE(obj))
+ {
+ case AGNODE:
+ deselect_node(g,obj);
+ break;
+ case AGEDGE:
+ deselect_edge(g,obj);
+ break;
+ case AGRAPH:
+ deselect_graph(g,obj);
+ break;
+ default:
+ break;
+ }
+}
+
+//select functions
+int select_graph(Agraph_t* g,Agraph_t* G)
+{
+ int ind=0;
+ //check if in the list
+ for (ind=0;ind < ((custom_graph_data*)AGDATA(g))->selectedGraphsCount ; ind ++ )
+ {
+ if(((custom_graph_data*)AGDATA(g))->selectedGraphs[ind] == G)
+ return 0;
+ }
+ //for single selections i think realloc is ok, for mass selections i ll figure out something else
+ ((custom_graph_data*)AGDATA(g))->selectedGraphs=realloc(((custom_graph_data*)AGDATA(g))->selectedGraphs,sizeof(Agnode_t*)*(((custom_graph_data*)AGDATA(g))->selectedGraphsCount+1));
+ ((custom_graph_data*)AGDATA(g))->selectedGraphs[((custom_graph_data*)AGDATA(g))->selectedGraphsCount]=G;
+ ((custom_graph_data*)AGDATA(g))->selectedGraphsCount++;
+ ((custom_object_data*)AGDATA(G))->Selected=1;
+}
+int deselect_node(Agraph_t* g,Agnode_t* N)
+{
+ int ind=0;
+ int valid=0;
+ //check if in the list
+ for (ind=0;ind < ((custom_graph_data*)AGDATA(g))->selectedNodesCount ; ind ++ )
+ {
+ if(valid)
+ ((custom_graph_data*)AGDATA(g))->selectedNodes[ind-1]=((custom_graph_data*)AGDATA(g))->selectedNodes[ind];
+ if( ((custom_graph_data*)AGDATA(g))->selectedNodes[ind] == N)
+ valid=1;
+ }
+ //for single selections i think realloc is ok, for mass selections i ll figure out something else
+ if(valid)
+ {
+ ((custom_graph_data*)AGDATA(g))->selectedNodes=realloc(((custom_graph_data*)AGDATA(g))->selectedNodes,sizeof(Agnode_t*)*(((custom_graph_data*)AGDATA(g))->selectedNodesCount-1));
+ ((custom_graph_data*)AGDATA(g))->selectedNodesCount--;
+ ((custom_object_data*)AGDATA(N))->Selected=0;
+ ((custom_object_data*)AGDATA(N))->selectionflag=0;
+ }
+
+
+}
+int deselect_edge(Agraph_t* g,Agedge_t* E)
+{
+ int ind=0;
+ int valid=0;
+ //check if in the list
+ for (ind=0;ind < ((custom_graph_data*)AGDATA(g))->selectedEdgesCount ; ind ++ )
+ {
+ if(valid)
+ ((custom_graph_data*)AGDATA(g))->selectedEdges[ind-1]=((custom_graph_data*)AGDATA(g))->selectedEdges[ind];
+ if( ((custom_graph_data*)AGDATA(g))->selectedEdges[ind] == E)
+ valid=1;
+ }
+ //for single selections i think realloc is ok, for mass selections i ll figure out something else
+ if(valid)
+ {
+ ((custom_graph_data*)AGDATA(g))->selectedEdges=realloc(((custom_graph_data*)AGDATA(g))->selectedEdges,sizeof(Agnode_t*)*(((custom_graph_data*)AGDATA(g))->selectedEdgesCount-1));
+ ((custom_graph_data*)AGDATA(g))->selectedEdgesCount--;
+ ((custom_object_data*)AGDATA(E))->Selected=0;
+ ((custom_object_data*)AGDATA(E))->selectionflag=0;
+
+ }
+}
+int deselect_graph(Agraph_t* g,Agraph_t* G)
+{
+ int ind=0;
+ int valid=0;
+ //check if in the list
+ for (ind=0;ind < ((custom_graph_data*)AGDATA(g))->selectedGraphsCount ; ind ++ )
+ {
+ if(valid)
+ ((custom_graph_data*)AGDATA(g))->selectedGraphs[ind-1]=((custom_graph_data*)AGDATA(g))->selectedGraphs[ind];
+ if( ((custom_graph_data*)AGDATA(g))->selectedGraphs[ind] == G)
+ valid=1;
+ }
+ //for single selections i think realloc is ok, for mass selections i ll figure out something else
+ if(valid)
+ {
+ ((custom_graph_data*)AGDATA(g))->selectedGraphs=realloc(((custom_graph_data*)AGDATA(g))->selectedGraphs,sizeof(Agnode_t*)*(((custom_graph_data*)AGDATA(g))->selectedGraphsCount-1));
+ ((custom_graph_data*)AGDATA(g))->selectedGraphsCount--;
+ ((custom_object_data*)AGDATA(G))->Selected=0;
+ ((custom_object_data*)AGDATA(G))->selectionflag=0;
+
+ }
+}
+
+int select_all_nodes(Agraph_t* g)
+{
+ Agnode_t *n;
+ for (n = agfstnode(g); n; n = agnxtnode(g, n))
+ {
+ select_node(g,n);
+ }
+ return 1;
+
+}
+int select_all_edges(Agraph_t* g)
+{
+ Agnode_t *n;
+ Agedge_t *e;
+
+
+ n = agfstnode(g);
+
+ for (n = agfstnode(g); n; n = agnxtnode(g, n))
+ {
+ for (e = agfstout(g,n) ; e ; e = agnxtout (g,e))
+ {
+ select_edge(g,e);
+ }
+ }
+ return 1;
+
+}
+int select_all_graphs(Agraph_t* g)
+{
+ Agraph_t *s;
+ for (s = agfstsubg(g); s; s = agnxtsubg(s))
+ select_graph(g,s);
+ return 1;
+}
+
+int deselect_all_nodes(Agraph_t* g)
+{
+ Agnode_t *n;
+
+
+ n = agfstnode(g);
+
+
+ for (n = agfstnode(g); n; n = agnxtnode(g, n))
+ {
+ deselect_node(g,n);
+ }
+ return 1;
+
+
+}
+int deselect_all_edges(Agraph_t* g)
+{
+{
+ Agnode_t *n;
+ Agedge_t *e;
+ n = agfstnode(g);
+ for (n = agfstnode(g); n; n = agnxtnode(g, n))
+ {
+ for (e = agfstout(g,n) ; e ; e = agnxtout (g,e))
+ {
+ deselect_edge(g,e);
+ }
+ }
+ return 1;
+}
+
+
+}
+int deselect_all_graphs(Agraph_t* g)
+{
+ Agraph_t *s;
+ for (s = agfstsubg(g); s; s = agnxtsubg(s))
+ deselect_graph(g,s);
+ return 1;
+}
+int select_all(Agraph_t* g)
+{
+ select_all_nodes(g);
+ select_all_edges(g);
+ select_all_graphs(g);
+ return 1;
+
+}
+int deselect_all(Agraph_t* g)
+{
+ deselect_all_nodes(g);
+ deselect_all_edges(g);
+ deselect_all_graphs(g);
+ return 1;
+}
+
+
+
+
--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#ifndef SELECTION_H
+#define SELECTION_H
+
+#include "viewport.h"
+
+#define SELECTION_SEGMENT_DIVIDER 5.0 //control points count to check if a line segment is withing clipping rect
+#define SINGLE_SELECTION_WIDTH 10 //width of the rect clip for single selections , higher values more catches less sensitivity
+
+int lineintersects(float X1,float X2,float Y1,float Y2);
+int rectintersects(float x,float y,float W,float H);
+int point_within_ellipse( xdot_op* op);
+int point_within_ellips_with_coords(float ex,float ey,float ea,float eb,float px,float py);
+int point_within_polygon(xdot_op* op);
+
+int is_point_in_rectangle(float X,float Y,float RX,float RY,float RW,float RH);
+int within_bezier(GLfloat* xp,GLfloat* yp,GLfloat* zp,int isx);
+
+int ellipse_in_rect(xdot_op* op);
+int ellipse_x_rect(xdot_op* op);
+
+
+int SelectBeziers(xdot_op* op);
+int SelectEllipse(xdot_op* op);
+int SelectPolygon(xdot_op* op);
+int SelectPolyline(xdot_op* op);
+int SelectText(xdot_op* op);
+int SelectImage(xdot_op* op);
+
+
+
+int spline_in_rect(xdot_op* op);
+int spline_x_rect(xdot_op* op);
+
+int polygon_int_rect(xdot_op* op);
+int polygon_x_rect(xdot_op* op);
+
+int polyline_in_rect(xdot_op* op);
+int polyline_x_rect(xdot_op* op);
+
+int text_in_rect(xdot_op* op);
+int text_x_rect(xdot_op* op);
+
+int image_in_rect(xdot_op* op);
+int image_x_rect(xdot_op* op);
+
+
+//select functions
+int select_graph(Agraph_t* g,Agraph_t*);
+int select_node(Agraph_t* g,Agnode_t*);
+int select_edge(Agraph_t* g,Agedge_t*);
+
+int select_object (Agraph_t* g,void* obj);
+int deselect_object (Agraph_t* g,void* obj);
+int deselect_graph(Agraph_t* g,Agraph_t*);
+int deselect_node(Agraph_t* g,Agnode_t*);
+int deselect_edge(Agraph_t* g,Agedge_t*);
+
+int select_all_nodes(Agraph_t* g);
+int select_all_edges(Agraph_t* g);
+int select_all_graphs(Agraph_t* g);
+
+
+int deselect_all_nodes(Agraph_t* g);
+int deselect_all_edges(Agraph_t* g);
+int deselect_all_gprahs(Agraph_t* g);
+
+int select_all(Agraph_t* g);
+int deselect_all(Agraph_t* g);
+
+
+#endif
--- /dev/null
+/* ====================================================================
+ * Copyright (c) 1999-2001 Carnegie Mellon University. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * This work was supported in part by funding from the Defense Advanced
+ * Research Projects Agency and the National Science Foundation of the
+ * United States of America, and the CMU Sphinx Speech Consortium.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
+ * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ *
+ */
+/*
+ * HISTORY
+ *
+ * 14-Oct-92 Eric Thayer (eht+@cmu.edu) Carnegie Mellon University
+ * added formal declarations for a and
+ * 14-Oct-92 Eric Thayer (eht+@cmu.edu) Carnegie Mellon University
+ * installed ulstrcmp() for strcasecmp() because DEC alpha for some reason
+ * seg faults on call to strcasecmp(). (OSF/1 BL8)
+ */
+
+/*
+ * case INSENSITIVE.
+ * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0
+ */
+
+static int
+ulstrcmp(char const *str1, char const *str2)
+{
+ register char c1,c2;
+
+ for(;;) {
+ c1 = *str1++;
+ if (c1 <= 'Z')
+ if (c1 >= 'A')
+ c1 += 040;
+ c2 = *str2++;
+ if (c2 <= 'Z')
+ if (c2 >= 'A')
+ c2 += 040;
+ if (c1 != c2)
+ break;
+ if (c1 == '\0')
+ return(0);
+ }
+ return(c1 - c2);
+}
+
+int
+mystrcasecmp (char const *a, char const *b)
+{
+ if (a && b)
+ return ulstrcmp(a,b);
+ else
+ return 1;
+}
+strcasecmp (char const *a, char const *b)
+{
+ if (a && b)
+ return ulstrcmp(a,b);
+ else
+ return 1;
+}
--- /dev/null
+/*
+ * strcasecmp.h -- string compare
+ *
+ * **********************************************
+ * CMU ARPA Speech Project
+ *
+ * Copyright (c) 1996 Carnegie Mellon University.
+ * ALL RIGHTS RESERVED.
+ * **********************************************
+ *
+ * HISTORY
+ *
+ * 14-Oct-92 Eric Thayer (eht+@cmu.edu) Carnegie Mellon University
+ * added formal declarations for a and
+ * 14-Oct-92 Eric Thayer (eht+@cmu.edu) Carnegie Mellon University
+ * installed ulstrcmp() for strcasecmp() because DEC alpha for some reason
+ * seg faults on call to strcasecmp(). (OSF/1 BL8)
+ */
+
+
+#ifndef _STRCASECMP_H_
+#define _STRCASECMP_H_
+
+extern int mystrcasecmp (char const *a, char const *b);
+
+#endif /* _STRCASECMP_H_ */