a0f5e0898b
which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
625 lines
13 KiB
C
Executable File
625 lines
13 KiB
C
Executable File
/* r4area.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */
|
|
|
|
#include "d4all.h"
|
|
|
|
/************************************************************
|
|
** Function: area4create()
|
|
*
|
|
* PARAMETERS:
|
|
* GROUP4* group - pointer to the containing GROUP4
|
|
* long height - height of the area in 1000's of an inch
|
|
* short is_header - flag indicating whether area is header or footer
|
|
* char* expression - character string for suppression condition
|
|
*
|
|
* DESCRIPTION: allocates the memory for an AREA4 and does initial setup
|
|
* of internal members, then adds to appropriate list in containing group
|
|
*
|
|
* RETURNS: an AREA4 pointer on success, NULL on failure
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
AREA4 * S4FUNCTION area4create( GROUP4 *group, long height, short is_header, char *expression )
|
|
{
|
|
AREA4 *area, *area_on;
|
|
EXPR4 *expr;
|
|
int i;
|
|
|
|
if( !group )
|
|
return NULL;
|
|
|
|
if( height < 0 )
|
|
{
|
|
e4describe( group->report->code_base, e4parm, E4_REP_AHEIGHT, 0, 0 );
|
|
return 0;
|
|
}
|
|
|
|
/* is suppression condition is provided, parse and check */
|
|
if( expression )
|
|
{
|
|
expr = expr4parse( group->report->relate->data, expression );
|
|
if( expr == 0 )
|
|
{
|
|
e4describe( group->report->code_base, e4area_create, E4_REP_AEXPR, 0, 0 );
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
expr = NULL;
|
|
|
|
/* allocate AREA4 */
|
|
area = (AREA4 *) u4alloc_free( group->report->code_base, sizeof(AREA4) );
|
|
if(area == 0)
|
|
{
|
|
e4describe( group->report->code_base, e4area_create, E4_REP_AMEM, 0, 0 );
|
|
return 0;
|
|
}
|
|
|
|
/* set internal members */
|
|
area->height = height;
|
|
area->suppression_condition = expr;
|
|
area->group = group;
|
|
area->allow_pagebreaks = 1;
|
|
area->report = group->report;
|
|
area->is_header = is_header;
|
|
|
|
/* insert AREA4 into appropriate list in GROUP4 struct and then re-number
|
|
the areas */
|
|
if( is_header )
|
|
{
|
|
l4add( &group->header_areas, area );
|
|
}
|
|
else
|
|
{
|
|
l4add( &group->footer_areas, area );
|
|
}
|
|
|
|
i = 1;
|
|
if( is_header )
|
|
area_on = (AREA4 *) l4first( &group->header_areas );
|
|
else
|
|
area_on = (AREA4 *) l4first( &group->footer_areas );
|
|
while(area_on )
|
|
{
|
|
area_on->position = i;
|
|
if( is_header )
|
|
area_on = (AREA4 *) l4next( &group->header_areas, area_on );
|
|
else
|
|
area_on = (AREA4 *) l4next( &group->footer_areas, area_on );
|
|
i++;
|
|
}
|
|
|
|
return area;
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4free()
|
|
*
|
|
* PARAMETERS: AREA4* area - pointer to area to be freed
|
|
*
|
|
* DESCRIPTION: frees the specified area, including any contained objects
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void S4FUNCTION area4free( AREA4 *area )
|
|
{
|
|
OBJ4 *obj_on;
|
|
|
|
/* free the supppression condition */
|
|
if( area->suppression_condition != NULL )
|
|
{
|
|
expr4free( area->suppression_condition );
|
|
}
|
|
|
|
/* free the contained objects */
|
|
while( (obj_on=(POBJ4)l4first(&area->objects)) != NULL )
|
|
{
|
|
obj4delete( obj_on );
|
|
}
|
|
|
|
/* Destroy the associated window */
|
|
#ifdef S4WINDOWS
|
|
if( area->hWnd )
|
|
{
|
|
DestroyWindow( area->hWnd );
|
|
area->hWnd = 0;
|
|
}
|
|
#endif
|
|
|
|
/* remove from the groups list */
|
|
if( area->is_header )
|
|
l4remove( &area->group->header_areas, area );
|
|
else
|
|
l4remove( &area->group->footer_areas, area );
|
|
|
|
/* free the memory */
|
|
u4free( area );
|
|
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4insert_object()
|
|
*
|
|
* PARAMETERS: LIST4* list - list to insert the object into
|
|
* POBJ4 obj - object to be inserted
|
|
*
|
|
* DESCRIPTION: inserts the object into the list, if the
|
|
* object falls within the boundaries of another object it
|
|
* is inserted into the bounding objects list
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void area4insert_object( LIST4 *list, POBJ4 obj )
|
|
{
|
|
POBJ4 obj_on;
|
|
|
|
obj_on = (POBJ4)l4first( list );
|
|
while( obj_on )
|
|
{
|
|
/* if the object is inside another object */
|
|
if( obj->x > obj_on->x && obj->y > obj_on->y &&
|
|
obj->w+obj->x < obj_on->w+obj_on->x &&
|
|
obj->h+obj->y < obj_on->h+obj_on->y )
|
|
{
|
|
obj->container = obj_on;
|
|
area4insert_object( &obj_on->contained, obj );
|
|
return;
|
|
}
|
|
obj_on = (POBJ4)l4next( list, obj_on );
|
|
}
|
|
|
|
/* add at beginning or end of list */
|
|
if( !obj->background )
|
|
l4add( list, obj );
|
|
else
|
|
l4add_before( list, l4first(list), obj );
|
|
return;
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4insert_y()
|
|
*
|
|
* PARAMETERS: LIST4* list - list to insert object into
|
|
* POBJ4 obj_out - object to be inserted
|
|
*
|
|
* DESCRIPTION: inserts the specified object into the list
|
|
* on the basis of the y coordinate
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void area4insert_y( LIST4 *list, POBJ4 obj_out )
|
|
{
|
|
POBJ4 obj_on;
|
|
int add_flag;
|
|
|
|
obj_on = (POBJ4)l4first( list );
|
|
if( !obj_on )
|
|
{
|
|
l4add( list, obj_out );
|
|
}
|
|
else
|
|
{
|
|
add_flag = 0;
|
|
while( obj_on )
|
|
{
|
|
if( obj_out->y < obj_on->y )
|
|
{
|
|
l4add_before( list, obj_on, obj_out );
|
|
add_flag = 1;
|
|
}
|
|
|
|
if( !add_flag )
|
|
obj_on = (POBJ4)l4next( list, obj_on );
|
|
else
|
|
obj_on = NULL;
|
|
}
|
|
if( !add_flag )
|
|
l4add( list, obj_out );
|
|
}
|
|
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4insert_xrev()
|
|
*
|
|
* PARAMETERS: LIST4* list - list to insert object into
|
|
* POBJ4 obj_out - object to be inserted
|
|
*
|
|
* DESCRIPTION: inserts the specified object into the list
|
|
* on the basis of the x coordinate
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void area4insert_xrev( LIST4 *list, POBJ4 obj_out )
|
|
{
|
|
POBJ4 obj_on;
|
|
int add_flag;
|
|
|
|
obj_on = (POBJ4)l4first( list );
|
|
if( !obj_on )
|
|
{
|
|
l4add( list, obj_out );
|
|
}
|
|
else
|
|
{
|
|
add_flag = 0;
|
|
while( obj_on )
|
|
{
|
|
if( obj_out->x > obj_on->x )
|
|
{
|
|
l4add_before( list, obj_on, obj_out );
|
|
add_flag = 1;
|
|
}
|
|
|
|
if( !add_flag )
|
|
obj_on = (POBJ4)l4next( list, obj_on );
|
|
else
|
|
obj_on = NULL;
|
|
}
|
|
if( !add_flag )
|
|
l4add( list, obj_out );
|
|
}
|
|
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4sort_list()
|
|
*
|
|
* PARAMETERS: LIST4 *list - list containing OBJ4 structures
|
|
*
|
|
* DESCRIPTION: sorts the list of objects
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void area4sort_list( LIST4 *list )
|
|
{
|
|
LIST4 hold_list, int_list;
|
|
POBJ4 obj_on, obj_out, obj_bound;
|
|
long ybound;
|
|
|
|
memset( &hold_list, 0, sizeof(LIST4) );
|
|
memset( &int_list, 0, sizeof(LIST4) );
|
|
|
|
while( (obj_out = (POBJ4)l4pop(list)) != NULL )
|
|
{
|
|
area4insert_y( &hold_list, obj_out );
|
|
}
|
|
|
|
while( hold_list.n_link > 0 )
|
|
{
|
|
obj_bound = (POBJ4)l4first( &hold_list );
|
|
l4remove( &hold_list, obj_bound );
|
|
area4insert_xrev( &int_list, obj_bound );
|
|
ybound = obj_bound->y;
|
|
obj_on = (POBJ4)l4first( &hold_list );
|
|
while( obj_on && obj_on->y == ybound )
|
|
{
|
|
l4remove( &hold_list, obj_on );
|
|
area4insert_xrev( &int_list, obj_on );
|
|
obj_on = (POBJ4)l4first( &hold_list );
|
|
}
|
|
|
|
while( (obj_out = (POBJ4)l4pop( &int_list)) != NULL )
|
|
l4add( list, obj_out );
|
|
}
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4add_object()
|
|
*
|
|
* PARAMETERS: AREA4* area - area to which an object is to be added
|
|
* OBJ4* obj_add - object to be added to the area
|
|
*
|
|
* DESCRIPTION: adds an object to the specified area
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void S4FUNCTION area4add_object( AREA4 *area, OBJ4 *obj_add )
|
|
{
|
|
POBJ4 pObj, pObjnext;
|
|
int i, j;
|
|
|
|
if( !area || !obj_add )
|
|
return;
|
|
|
|
obj_add->container = NULL;
|
|
area4insert_object( &area->objects, obj_add );
|
|
if( obj_add->x == 0 && obj_add->y == 0 && obj_add->w == 0 && obj_add->h == 0 )
|
|
return;
|
|
|
|
pObj = (POBJ4)l4first( &area->objects );
|
|
j = area->objects.n_link;
|
|
i = 0;
|
|
while( pObj && i < j )
|
|
{
|
|
pObjnext = (POBJ4)l4next( &area->objects, pObj );
|
|
if( pObj->x > obj_add->x && pObj->y > obj_add->y &&
|
|
pObj->w + pObj->x < obj_add->w + obj_add->x &&
|
|
pObj->h + pObj->y < obj_add->h + obj_add->y )
|
|
{
|
|
l4remove( &area->objects, pObj );
|
|
area4insert_object( &area->objects, pObj );
|
|
}
|
|
pObj = pObjnext;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4sort_obj_tree()
|
|
*
|
|
* PARAMETERS: PAREA4 area - pointer to the AREA4 struct containing the
|
|
* objects to be sorted
|
|
*
|
|
* DESCRIPTION: sorts the objects in the areas object tree
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
void S4FUNCTION area4sort_obj_tree( PAREA4 area )
|
|
{
|
|
POBJ4 obj_on;
|
|
|
|
area4sort_list( &area->objects );
|
|
obj_on = (POBJ4)l4first( &area->objects );
|
|
while( obj_on )
|
|
{
|
|
if( obj_on->contained.n_link > 0 )
|
|
area4sort_list( &obj_on->contained );
|
|
obj_on = (POBJ4)l4next( &area->objects, obj_on );
|
|
}
|
|
}
|
|
|
|
/************************************************************
|
|
** Function: area4pageBreak()
|
|
*
|
|
* PARAMETERS: PAREA4 area - area to toggle break flag of
|
|
* int breaks - new value for flag
|
|
*
|
|
* DESCRIPTION: toggles the flag allowing page breaks within the area
|
|
*
|
|
* RETURNS: the previous value of the flag
|
|
*
|
|
* By: Raymond Cypher
|
|
*
|
|
* HISTORY:
|
|
*
|
|
*/
|
|
int S4FUNCTION area4pageBreak( PAREA4 area, int breaks )
|
|
{
|
|
int temp;
|
|
|
|
if( area == NULL || breaks < 0 )
|
|
{
|
|
if( area )
|
|
e4describe( area->report->code_base, e4parm, E4_REP_PGBRK, 0, 0 );
|
|
return -1;
|
|
}
|
|
|
|
temp = area->allow_pagebreaks;
|
|
area->allow_pagebreaks = breaks;
|
|
|
|
return temp;
|
|
}
|
|
|
|
/****************************************************************************
|
|
The rest of the functions contained in this file are documented in the
|
|
CodeReporter manual.
|
|
*/
|
|
PAREA4 S4FUNCTION group4headerFirst( PGROUP4 group )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4first( &group->header_areas );
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4headerNext( PGROUP4 group, PAREA4 area )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4next( &group->header_areas, area );
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4headerLast( PGROUP4 group )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4last( &group->header_areas );
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4headerPrev( PGROUP4 group, PAREA4 area )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4prev( &group->header_areas, area );
|
|
}
|
|
|
|
int S4FUNCTION group4numHeaders( PGROUP4 group )
|
|
{
|
|
if( !group )
|
|
return 0;
|
|
|
|
return group->header_areas.n_link;
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4footerFirst( PGROUP4 group )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4first( &group->footer_areas );
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4footerNext( PGROUP4 group, PAREA4 area )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4next( &group->footer_areas, area );
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4footerLast( PGROUP4 group )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4last( &group->footer_areas );
|
|
}
|
|
|
|
PAREA4 S4FUNCTION group4footerPrev( PGROUP4 group, PAREA4 area )
|
|
{
|
|
if( !group )
|
|
return NULL;
|
|
|
|
return (PAREA4)l4prev( &group->footer_areas, area );
|
|
}
|
|
|
|
int S4FUNCTION group4numFooters( PGROUP4 group )
|
|
{
|
|
if( !group )
|
|
return 0;
|
|
|
|
return group->footer_areas.n_link;
|
|
}
|
|
|
|
|
|
POBJ4 S4FUNCTION area4objFirst( PAREA4 area )
|
|
{
|
|
if( !area )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return (POBJ4)l4first( &area->objects );
|
|
}
|
|
|
|
POBJ4 S4FUNCTION area4objNext( PAREA4 area, POBJ4 aobj )
|
|
{
|
|
POBJ4 next_obj, obj;
|
|
|
|
if( !area || !aobj )
|
|
{
|
|
if( area && !aobj )
|
|
e4describe( area->report->code_base, e4parm, E4_REP_OBJNXT, 0, 0 );
|
|
return NULL;
|
|
}
|
|
|
|
obj = aobj;
|
|
|
|
if( obj->contained.n_link > 0 )
|
|
{
|
|
return (POBJ4)l4first( &obj->contained );
|
|
}
|
|
|
|
for( ;; )
|
|
{
|
|
if( !obj )
|
|
return obj;
|
|
|
|
if( obj->container == 0 )
|
|
{
|
|
return (POBJ4)l4next( &area->objects, obj );
|
|
}
|
|
|
|
next_obj = (POBJ4)l4next( &obj->container->contained, obj );
|
|
if( next_obj )
|
|
return next_obj;
|
|
|
|
obj = obj->container;
|
|
}
|
|
|
|
}
|
|
|
|
POBJ4 S4FUNCTION area4objPrev( PAREA4 area, POBJ4 aobj )
|
|
{
|
|
POBJ4 prev_obj, obj;
|
|
|
|
if( !area || !aobj )
|
|
{
|
|
if( area && !aobj )
|
|
e4describe( area->report->code_base, e4parm, E4_REP_OBJPRV, 0, 0 );
|
|
return NULL;
|
|
}
|
|
|
|
prev_obj = area4objFirst( area );
|
|
if( prev_obj == aobj )
|
|
return NULL;
|
|
|
|
obj = area4objNext( area, prev_obj );
|
|
while( obj && obj != aobj )
|
|
{
|
|
prev_obj = obj;
|
|
obj = area4objNext( area, prev_obj );
|
|
}
|
|
|
|
return prev_obj;
|
|
|
|
}
|
|
|
|
POBJ4 S4FUNCTION area4objLast( PAREA4 area )
|
|
{
|
|
POBJ4 obj, prev_obj;
|
|
|
|
if( !area )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prev_obj = area4objFirst( area );
|
|
obj = area4objNext( area, prev_obj );
|
|
while( obj != NULL )
|
|
{
|
|
prev_obj = obj;
|
|
obj = area4objNext( area, prev_obj );
|
|
}
|
|
|
|
return prev_obj;
|
|
}
|
|
|
|
int S4FUNCTION area4numObjects( PAREA4 area )
|
|
{
|
|
int objcount;
|
|
POBJ4 obj;
|
|
|
|
if( !area )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
objcount = 0;
|
|
obj = area4objFirst( area );
|
|
while( obj )
|
|
{
|
|
objcount++;
|
|
obj = area4objNext( area, obj );
|
|
}
|
|
|
|
return objcount;
|
|
}
|