/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#ifndef __RECTLIST_HPP_
#define __RECTLIST_HPP_
#include "arch.hh"
#include "memory/lalloc.hh"
#include "isllist.hh"
/*
A rect list manages a list of disjoint rectangles. This is used for clipping, dirty_rectangles,
and a few other misc. things. The operations should be straitforward.
The rectlist is actually just a point to a list of area nodes. Rectlist should be passed as
a reference.
ussage example :
// create a list containing the rectangle [0,0-320,200]
i4_rectlist l(0,0,320,200);
// list now contains the area above minus the area in the rectangle [5,5,320-5,200-5]
l.remove_area(5,5,320-5,200-5);
// list now conains the areas [100,0,105,5] & [100,200-5,105,200]
l. intersect_area(100,0,105,200);
*/
class i4_rect_list_class
{
public:
class area
{
public :
typedef i4_linear_allocator area_allocator;
static area_allocator *area_alloc;
i4_coord x1,y1,x2,y2;
area *next;
#ifndef __MAC__
area(i4_coord X1, i4_coord Y1,i4_coord X2,i4_coord Y2)
{
x1=X1; y1=Y1;
x2=X2; y2=Y2;
}
#ifndef i4_NEW_CHECK
void *operator new(size_t size)
{
return area_alloc->alloc();
}
void operator delete(void *ptr)
{
area_alloc->free((area *)ptr);
}
#endif
#endif
};
#ifdef __MAC__
area *new_area(i4_coord X1, i4_coord Y1, i4_coord X2, i4_coord Y2)
{
area *r = (area *)area::area_alloc->alloc();
r->x1=X1; r->y1=Y1;
r->x2=X2; r->y2=Y2;
return r;
}
void delete_area(area *ptr)
{
area::area_alloc->free(ptr);
}
#else
area *new_area(i4_coord X1, i4_coord Y1, i4_coord X2, i4_coord Y2)
{
return new area(X1,Y1,X2,Y2);
}
void delete_area(area *ptr) { delete ptr; }
#endif
private:
public:
typedef i4_isl_list::iterator area_iter;
i4_isl_list list;
i4_rect_list_class() {}
i4_rect_list_class(i4_rect_list_class *copy_from, i4_coord xoff, i4_coord yoff);
// initial size of rect area
i4_rect_list_class(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2)
{ list.insert(*(new_area(x1,y1,x2,y2))); }
// exchanges the contents of two rect_list : used to replace the display's clip list
void swap(i4_rect_list_class *other);
i4_bool empty() { return list.empty(); }
void delete_list()
{
area *a;
while (!empty())
{
a = &*list.begin();
list.erase();
delete_area(a);
}
}
// subtracts this area from rect rects
void remove_area(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2);
// combines this area with rects in list
void add_area(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2,
i4_bool combine=i4_F);
// reduces area list to that which intersects this area
void intersect_area(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2);
// reduces area list to that which intersects this area list
void intersect_list(i4_rect_list_class *other);
// return i4_T if area is totally clipped away
// this can be used to skip expensive drawing operations
i4_bool clipped_away(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2);
// debuggin purposes only
void inspect(int print=0);
~i4_rect_list_class() { delete_list(); }
} ;
#endif
//{{{ Emacs Locals
// Local Variables:
// folded-file: t
// End:
//}}}