Source of rectangle.h


/* rectangle.h -- special rectangle support for gemsvnc */

#ifndef __rectangle__h__
#define __rectangle__h__

/* We need to work with collections of rectangles of pixels in the framebuffer.  The edges of these rectamgles are always parallel
   to the edges of the framebuffer itself, and therefore to all the other rectangles in the collections.  The rectangles may or
   may not overlap.  Perhaps the rectangles may not always be wholy contained within the framebuffer.  Thus we see that the
   framebuffer is also a rectangle meeting these constraints.

   It is not necessarily known in advance how many rectangles might belong to any given set; therefore, we will implement these
   sets as linked list data structures, with the nodes being dynamically allocated and freed.  Because we will need to insert and
   remove arbitrary rectangles from these sets, we use a doubly linked list representation for these sets.  Because insertion and
   deletion routines are simpler on circularly linked doubly linked lists, we use a circular representation in preference to a
   null terminated representation.

   This representation should be hiddin within the list of rectangles, as it could be changed to a tree, a priority queue, or
   something else in the interests of efficiency.  Always use the provided methods, and not a priori knowledge of the
   representation of the objects when making use of these objects. */


/* we need to use regular expressions for rectangle name globbing */
#include <sys/types.h>
#include <regex.h>

/* we need to know the largest and smallest possible integers to initialize the bounding box */
#include <limits.h>


/* class rectangle */

typedef struct _rectangle {                                      /* a rectangle */

  struct _rectangle* next;                                       /* link to next rectangle in list */
  struct _rectangle* prev;                                       /* link to previous rectangle in list */

  char* name;                                                    /* the name of this rectangle */

  int ul_x, ul_y;                                                /* upper left corner */
  int lr_x, lr_y;                                                /* lower right corner */

} rectangle;


rectangle* construct_rectangle(int ulx, int uly, int lrx, int lry, char* name);        /* This constructor returns a rectangle object
                                                                                   which may make use of dynamicly allocated
                                                                                   memory.  For this reason, all rectangle objects
                                                                                   constructed by means of this constructor should
                                                                                   be destroyed by calling the corresponding
                                                                                   destructor. */


void destruct_rectangle(rectangle* R);                           /* This destructor properly gets rid of a rectangle object
                                                                    constructed by the above constructort.  Since this may involve
                                                                    the releasing of dynamically allocated memory, all rectangles
                                                                    constructed by construct_rectangle should be destroyed by
                                                                    destruct_rectangle. */


void show_rectangle(rectangle* R);                               /* show a rectangle in human readable form */


void insert_rectangle_before(rectangle* S, rectangle* R);        /* This method inserts rectangle R so that it immediately
                                                                    preceeds rectangle S in the list that rectangle S belongs
                                                                    to.  */


void insert_rectangle_after(rectangle* S, rectangle* R);         /* insert R after S in the list S is on */      


void remove_rectangle_from_list(rectangle* R);                   /* remove R from whatever list it might be on */


rectangle* find_rectangle_on_list(rectangle* L, char* re);       /* determine whether a rectangle is on a list L */


int area(rectangle* R);                                          /* return the area of a rectangle */


int point_is_in_interval_P(int a, int b, int c);                 /* is b between a and c? */


int point_is_inside_rectangle_P(int x, int y, rectangle* R);     /* is the point inside the rectangle? */


rectangle* construct_empty_list_of_rectangles(char* name);       /* construct the list head for a list of rectangles, initially
                                                                    empty */


void update_bounding_box(rectangle* L, rectangle* R);            /* update bounding box in list head L to included rectangle R */


void add_rectangle_to_list(rectangle* L, rectangle* R);          /* add a rectangle to a list of rectangles. */


rectangle* remove_named_rectangle_from_list(rectangle* L, char* re); /* remove a rectangle with the same corners */


void destroy_named_rectangle_on_list(rectangle* L, char* re);    /* search and destroy a named rectangle */

/* The iterator over lists of rectangles.

   Usage:

    rectangle* list;
    rectangle* R;
    state_rectangle_list_iterator* context;

    for (R = initial_rectangle_list_iterator(list, &context);
         continue_rectangle_list_iterator(&context);
         R = next_rectangle_list_iterator(&context)) {
         do_something(R);
    }
*/

typedef struct _state_rectangle_list_iterator {                  /* the state of a rectangle list iterator */
  rectangle* head;                                               /* pointer to the list head */
  rectangle* current;                                            /* pointer to the current rectangle */
} state_rectangle_list_iterator;

rectangle* initial_rectangle_list_iterator(rectangle* list, state_rectangle_list_iterator** context); /* initialize an iterator */
int continue_rectangle_list_iterator(state_rectangle_list_iterator** context); /* test an iterator for non-completion */
rectangle* next_rectangle_list_iterator(state_rectangle_list_iterator** context); /* get the next item */


void reposition_rectangle_on_list(rectangle* list, rectangle* r, int ulx, int uly, int lrx, int lry); 

rectangle* intersection_of_2_rectangles(rectangle* R1, rectangle* R2, char* name);

#endif /* __rectangle__h__ */