/* r4driver.c (c)Copyright Sequiter Software Inc., 1991-1994. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #ifndef S4WINDOWS #include #endif #endif #ifdef S4TEMP #include "t4test.h" #endif #include #ifndef S4UNIX #ifndef S4IBMOS2 #ifndef __TURBOC__ #include #define S4LOCKING #endif #ifdef __ZTC__ extern int errno ; #endif #ifdef _MSC_VER #include #include #endif #ifdef __TURBOC__ /* extern int cdecl errno ; */ #endif #endif #include #include #endif #ifdef S4MACINTOSH #include #endif #include #include #ifdef S4DO_ERRNO extern int errno ; #endif #define ABS(x) ((x<0)?-1*(x):x) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #ifdef S4WINDOWS extern HINSTANCE hInst; #endif int report4calc_page_height( REPORT4 *report ) { int retval; AREA4 *area_on; if( report->for_dbf ) return 31000; retval = (int)(report->dev_page_height - report->dev_margin_bottom); area_on = (AREA4 *)l4first( &report->page_header_footer->footer_areas ); while( area_on ) { if( area_on->suppression_condition ) { if( !expr4true( area_on->suppression_condition ) ) retval -= area_on->height_dev; } else retval -= area_on->height_dev; area_on = (AREA4 *)l4next( &report->page_header_footer->footer_areas, area_on ); } return retval; } #ifdef S4WINDOWS #ifdef __cplusplus int report4output_group_headers( GROUP4 *group, HDC hDC, GROUP4 *group_first, int use_break ) #else int report4output_group_headers(group, hDC, group_first, use_break ) GROUP4 *group ; HDC hDC ; GROUP4 *group_first ; int use_break ; #endif #else #ifdef __cplusplus int report4output_group_headers( GROUP4 *group, PAGE4 *hDC, GROUP4 *group_first, int use_break ) #else int report4output_group_headers(group, hDC, group_first, use_break ) GROUP4 *group ; PAGE4 *hDC ; GROUP4 *group_first ; int use_break ; #endif #endif { REPORT4 *report = group->report; AREA4 *area_on = report->area_on, *garea_on; int aflag, area_height; if( group->title_summary ) group->tsdone = 1; aflag = 0; garea_on = (PAREA4)l4first( &group->header_areas ); while( garea_on ) { if( garea_on == area_on ) aflag = 1; garea_on = (PAREA4)l4next( &group->header_areas, garea_on ); } if( !aflag ) area_on = NULL; if( (group->reset_page || group->reset_pagenum || group->swap_header) && (group == group_first || report->hard_resets_flag) && report->first ) { if( !group->reset_flag ) { group->reset_flag = 1; report4output_pgfooter( report, hDC ); report->group_on = group; report->group_first = group_first; report->area_on = NULL; report->in_header = 1; return 0; } else { group->reset_flag = 0; } } if( !area_on ) area_on = (AREA4 *)l4first( &group->header_areas ); while( area_on ) { if( !report->broken ) area_height = area_on->height_dev + report->ypos; else if( report->broken == 2 ) area_height = (area_on->height_dev - report->break_height) + report->ypos; else if( report->broken == 1 ) area_height = report->break_height + report->ypos; if( area_height > report->disp_bottom ) { if( area_on->allow_pagebreaks ) { report->break_height = report4output_area_break( area_on ); if( report->break_height ) { report->broken = 1; report4output_area( area_on, hDC, 1 ); } } report4output_pgfooter( report, hDC ); report->group_on = group; report->group_first = group_first; report->area_on = area_on; report->in_header = 1; return 0; } report4output_area( area_on, hDC, use_break ); area_on = (AREA4 *)l4next( &group->header_areas, area_on ); } if( group->title_summary && group->report->pgbrk_title && group->header_areas.n_link > 0 ) { report->group_on = (PGROUP4)l4next( &group->report->groups, group ); report->group_first = group_first; report->area_on = NULL; report->in_header = 1; return 0; } return 1; } #ifdef S4WINDOWS #ifdef __cplusplus int report4output_group_footers(GROUP4 *group, HDC hDC, GROUP4 *group_first ) #else int report4output_group_footers(group, hDC, group_first ) GROUP4 *group ; HDC hDC ; GROUP4 *group_first ; #endif #else #ifdef __cplusplus int report4output_group_footers(GROUP4 *group, PAGE4 *hDC, GROUP4 *group_first ) #else int report4output_group_footers(group, hDC, group_first ) GROUP4 *group ; PAGE4 *hDC ; GROUP4 *group_first ; #endif #endif { long theight; REPORT4 *report = group->report; AREA4 *area_on = report->area_on, *harea; int area_height; if( !area_on ) area_on = (AREA4 *)l4first( &group->footer_areas ); harea = area_on; theight = 0; while( harea ) { if( !harea->suppression_condition || expr4true(harea->suppression_condition) ) theight += harea->height_dev; harea = (PAREA4)l4next( &group->footer_areas, harea ); } if( group->swap_footer ) if( (report->page_header_footer && report->page_header_footer->footer_areas.n_link > 0) || report->ypos < report->disp_bottom - theight ) if( group == group_first || report->hard_resets_flag || ( group_first == report->title_summary && group == (PGROUP4)l4next( &report->groups, report->title_summary)) ) { report4output_swapped_footer( group, hDC ); report->group_on = (GROUP4 *)l4prev( &report->groups, group ); if( report->group_on == report->title_summary ) { if( !report->end_report ) { report->group_on = (PGROUP4)l4next( &report->groups, report->group_on ); report->in_header = 1; report4swap_old_rec( report ); report->group_first = NULL; } else { if( report->group_on->footer_areas.n_link <= 0 ) report->end_report = 2; report->in_header = 0; report->group_first = group_first; } } else { report->in_header = 0; report->group_first = group_first; } report->area_on = NULL; return 0; } while( area_on ) { if( !report->broken ) area_height = area_on->height_dev + report->ypos; else if( report->broken == 2 ) area_height = (area_on->height_dev - report->break_height) + report->ypos; else if( report->broken == 1 ) area_height = report->break_height + report->ypos; if( area_height > report->disp_bottom ) { report->break_height = report4output_area_break( area_on ); if( report->break_height ) { report->broken = 1; report4output_area( area_on, hDC, 1 ); } report4output_pgfooter( report, hDC ); report->group_on = group; report->group_first = group_first; report->area_on = area_on; report->in_header = 0; return 0; } report4output_area( area_on, hDC, 1 ); area_on = (AREA4 *)l4next( &group->footer_areas, area_on ); } return 1; } #ifdef S4WINDOWS #ifdef __cplusplus int S4FUNCTION report4generatePage(PREPORT4 report, HDC hDC ) #else int S4FUNCTION report4generatePage(report, hDC ) PREPORT4 report ; HDC hDC ; #endif #else #ifdef __cplusplus int S4FUNCTION report4generatePage( PREPORT4 report ) #else int S4FUNCTION report4generatePage(report ) PREPORT4 report ; #endif #endif { GROUP4 *group_first, *group_on; TOTAL4 *total_on; int rc, flag; #ifndef S4WINDOWS PAGE4 *hDC; #endif #ifdef S4DEBUG if( !report ) return -1; #ifdef S4WINDOWS if( !hDC && !report->for_dbf ) return -1; #endif if( report->code_base->error_code < 0 ) return -1; #endif #ifndef S4WINDOWS hDC = &report->page_buf; #ifdef S4NO_CHSIZE file4change_size( &report->page_buf.file_buf, 0L ); #else chsize( report->page_buf.file_buf.hand, 0L ); #endif file4seq_write_init( &hDC->seq_wr, &hDC->file_buf, 0L, hDC->fmem_buf, sizeof(hDC->fmem_buf) ); #endif if( report->end_report == 2 ) return 2; report->code_base->pageno++; report->page_count++; report->ypos = report->dev_margin_top; report->disp_bottom = report4calc_page_height( report ); group_first = report->group_first; group_on = report->group_on; flag = report->in_header; if( group_on && group_on->reset_pagenum ) report->code_base->pageno = 1; if( report->tdone == 0 ) { report->tdone = 1; total_on = (TOTAL4 *)l4first( &report->code_base->total_list ); while( total_on ) { if( !total_on->obj || !total_on->obj->lookahead ) total4value_update( total_on ); total_on = (TOTAL4 *)l4next( &report->code_base->total_list, total_on ); } } if( group_first == NULL && group_on == report->title_summary ) { if( group_on->lookahead ) report4evaluate_lookahead( group_on ); if( (report4output_group_headers( group_on, hDC, group_first, 1 )) == 0 ) goto GOODRET; report->first = group_on->position; group_on = (GROUP4 *)l4next( &report->groups, group_on ); } if( !group_on || (group_on && !group_on->swap_header) ) report4output_pgheader( report, hDC ); else { if( flag ) { report4output_group_headers( group_on, hDC, group_first, 1 ); group_on = (GROUP4 *)l4next( &report->groups, group_on ); } } if( report->code_base->pageno > 1 ) report4output_repeat_headers( report, hDC, group_first ); while( 1 ) { report->disp_bottom = report4calc_page_height( report ); if( flag ) { if( report->tdone == 0 ) { report->tdone = 1; total_on = (TOTAL4 *)l4first( &report->code_base->total_list ); while( total_on ) { if( !total_on->obj || !total_on->obj->lookahead ) total4value_update( total_on ); total_on = (TOTAL4 *)l4next( &report->code_base->total_list, total_on ); } } if( !group_on ) group_on = (GROUP4 *)l4first( &report->groups ); if( group_on->title_summary && group_on->tsdone > 0 ) group_on = (PGROUP4)l4next( &report->groups, group_on ); while( group_on ) { if( group_on->lookahead ) report4evaluate_lookahead( group_on ); if( (report4output_group_headers( group_on, hDC, group_first, 1 )) == 0 ) goto GOODRET; report->first = group_on->position; group_on = (GROUP4 *)l4next( &report->groups, group_on ); } report4make_old_rec( report ); while( (rc = relate4skip( report->relate, 1L )) == 0 ) { report->tdone = 0; group_first = report4calc_first_change_group( report ); if( group_first ) break; else { report4make_old_rec( report ); if( report->tdone == 0 ) { report->tdone = 1; total_on = (TOTAL4 *)l4first( &report->code_base->total_list ); while( total_on ) { if( !total_on->obj || !total_on->obj->lookahead ) total4value_update( total_on ); total_on = (TOTAL4 *)l4next( &report->code_base->total_list, total_on ); } } } } if( rc == r4eof ) { group_first = (GROUP4 *)l4first( &report->groups ); report->end_report = 1; } if( group_first == NULL ) group_first = (GROUP4 *)l4first( &report->groups ); if( group_first->position == 0 && group_first->footer_areas.n_link == 0 ) group_first = (GROUP4 *)l4next( &report->groups, group_first ); report4swap_old_rec( report ); } report->tdone = 1; flag = 1; report->area_on = NULL; if( !group_on ) group_on = (GROUP4 *)l4last( &report->groups ); while( group_on ) { if( (report4output_group_footers( group_on, hDC, group_first )) == 0 ) { if( group_on == group_first && report->end_report == 1 && report->broken != 2) { report->end_report = 2; report->tdone = 0; } if( report->for_dbf && report->output_group == group_on ) { file4seq_write( &report->dfile_seq, d4record(report->data_file), (unsigned)(d4record_width(report->data_file)) ); report->rcount++; } goto GOODRET; } if( report->for_dbf && report->output_group == group_on ) { file4seq_write( &report->dfile_seq, d4record(report->data_file), (unsigned)(d4record_width(report->data_file)) ); report->rcount++; } if( group_on == group_first ) break; group_on = (GROUP4 *)l4prev( &report->groups, group_on ); } if( report->end_report == 1) { report->end_report = 2; report4output_pgfooter( report, hDC ); break; } report->tdone = 0; report4swap_old_rec( report ); } GOODRET: #ifndef S4WINDOWS file4seq_write_flush( &report->page_buf.seq_wr ); report->page_buf.first_read = 0; #endif return 0; } #ifdef S4WINDOWS #ifdef __cplusplus int report4output_area(PAREA4 area, HDC hDC, int use_break ) #else int report4output_area(area, hDC, use_break ) PAREA4 area ; HDC hDC ; int use_break ; #endif #else #ifdef __cplusplus int report4output_area(PAREA4 area, PAGE4 *hDC, int use_break ) #else int report4output_area(area, hDC, use_break ) PAREA4 area ; PAGE4 *hDC ; int use_break ; #endif #endif { OBJ4 *obj_on; int suppress = 0; if( area->suppression_condition ) { suppress = expr4true( area->suppression_condition ); } if( suppress ) { if ( area->height_dev > area->report->break_height ) { area->report->broken = 0; area->report->break_height = 0L; } return 0; } obj_on = (OBJ4 *)l4first( &area->objects ); while( obj_on ) { if( area->report->broken == 0 || use_break == 0 ) { report4output_object( obj_on, hDC ); } else if( area->report->broken == 1 ) { if( obj_on->dev_y <= area->report->break_height ) { report4output_object( obj_on, hDC ); } } else if( area->report->broken == 2 ) { if( obj_on->dev_y >= area->report->break_height ) { report4output_object( obj_on, hDC ); } } obj_on = (OBJ4 *)l4next( &area->objects, obj_on ); } if( area->report->broken == 1 ) { area->report->broken = 2; return 0; } if( area->report->broken == 2 ) { if( area->report->for_dbf ) { area->report->ypos = 0; } else { area->report->ypos += (area->height_dev - area->report->break_height ); } area->report->broken = 0; area->report->break_height = 0L; return 0; } if( area->report->for_dbf ) area->report->ypos = 0; else area->report->ypos += area->height_dev; return 0; } #ifdef S4WINDOWS #ifdef __cplusplus int report4output_object(POBJ4 obj, HDC hDC ) #else int report4output_object(obj, hDC ) POBJ4 obj ; HDC hDC ; #endif #else #ifdef __cplusplus int report4output_object(POBJ4 obj, PAGE4 *hDC ) #else int report4output_object(obj, hDC ) POBJ4 obj ; PAGE4 *hDC ; #endif #endif { REPORT4 *report; char *output_ptr, *cptr; long len; int offset_break; OBJ4 *obj_on; #ifdef S4WINDOWS PBITMAPINFO pbmi; HANDLE hDIB; HPEN hpen; HBRUSH hbrush; LOGBRUSH lbrush; RECT rect; UINT alignment; POINT pt; int lwidth, sdc; #else long lval, obj_len, data_len; int i; #endif #ifdef S4DEBUG if( !obj || (!hDC && !obj->area->report->for_dbf) ) { return 0; } #endif report = obj->area->report; if( report->output_code != 1 ) if( !(report->start_page == 0 && report->end_page == 0) ) if( report->page_count < report->start_page || report->page_count > report->end_page ) return(0); #ifdef S4WINDOWS SetBkMode( hDC, TRANSPARENT ); #endif if( report->code_base->error_code < 0 ) return -1; output_ptr = NULL; if( report->broken == 2 ) offset_break = (int)report->break_height; else offset_break = 0; if( obj->display_once && obj->display_once_expr && obj->last_display_val ) { len = expr4vary( obj->display_once_expr, &cptr ); if( memcmp(obj->last_display_val, cptr, (int)len ) == 0 ) return 0; memcpy( obj->last_display_val, cptr, (int)len ); } switch( obj->obj_type_num ) { #ifdef S4WINDOWS case obj4type_bitmap3: if( report->for_dbf ) break; if( !obj->lookahead ) obj4evaluate( obj ); if( obj->eval_text ) { hDIB = GetDIB( obj->eval_text, obj->area->report->code_base ); if( !hDIB ) break; pbmi = (PBITMAPINFO)GlobalLock(hDIB); StretchDIBits( hDC, (int)(obj->dev_x + report->dev_margin_left), (int)(obj->dev_y + report->ypos - offset_break), (int)(obj->dev_w), (int)(obj->dev_h), 0, 0, (int)pbmi->bmiHeader.biWidth, (int)pbmi->bmiHeader.biHeight, (LPSTR)FindDIBBits((LPSTR)pbmi), pbmi, DIB_RGB_COLORS, SRCCOPY ); GlobalUnlock( hDIB ); GlobalFree( hDIB ); } break; case obj4type_bitmap1: case obj4type_bitmap2: if( report->for_dbf ) break; pbmi = (PBITMAPINFO)GlobalLock((HANDLE)obj->data); StretchDIBits( hDC, (int)(obj->dev_x + report->dev_margin_left), (int)(obj->dev_y + report->ypos - offset_break), (int)obj->dev_w, (int)obj->dev_h, 0, 0, (int)pbmi->bmiHeader.biWidth, (int)pbmi->bmiHeader.biHeight, (LPSTR)FindDIBBits((LPSTR)pbmi), pbmi, DIB_RGB_COLORS, SRCCOPY ); GlobalUnlock((HANDLE)obj->data); break; case obj4type_hline: case obj4type_vline: case obj4type_frame: if( report->for_dbf ) break; sdc = SaveDC( hDC ); SetMapMode( hDC, MM_HIENGLISH ); SetMapMode( hDC, MM_ANISOTROPIC ); pt.x = obj->dec; LPtoDP( hDC, &pt, 1 ); lwidth = pt.x; RestoreDC( hDC, sdc ); hbrush = NULL; hpen = NULL; if( obj->style ) { lbrush.lbColor = obj->style->color; lbrush.lbStyle = BS_SOLID; lbrush.lbHatch = 0L; hbrush = CreateBrushIndirect( &lbrush ); hpen = CreatePen( PS_SOLID, lwidth, obj->style->color ); } if( hbrush && hpen ) { SelectObject( hDC, hbrush ); SelectObject( hDC, hpen ); } else { SelectObject( hDC, GetStockObject(BLACK_PEN) ); SelectObject( hDC, GetStockObject(BLACK_BRUSH) ); } if( obj->obj_type_num == obj4type_hline ) { MoveToEx( hDC, (int)(obj->dev_x + report->dev_margin_left), (int)(obj->dev_y + obj->dev_h/2 + report->ypos - offset_break), NULL ); LineTo( hDC, (int)(obj->dev_x + obj->dev_w + report->dev_margin_left), (int)(obj->dev_y + obj->dev_h/2 + report->ypos - offset_break) ); } if( obj->obj_type_num == obj4type_vline ) { MoveToEx( hDC, (int)(obj->dev_x + obj->dev_w/2 + report->dev_margin_left), (int)(obj->dev_y + report->ypos - offset_break), NULL ); LineTo( hDC, (int)(obj->dev_x + obj->dev_w/2 + report->dev_margin_left), (int)(obj->dev_y + obj->dev_h + report->ypos - offset_break) ); } if( obj->obj_type_num == obj4type_frame ) { if( !obj->display_zero ) SelectObject( hDC, GetStockObject( WHITE_BRUSH ) ); if( obj->alignment == 0 ) { Rectangle( hDC, (int)(obj->dev_x + report->dev_margin_left + 1 + (lwidth/2)), (int)(obj->dev_y + report->ypos - offset_break + 1 + (lwidth/2)), (int)(obj->dev_x + obj->dev_w + report->dev_margin_left - (lwidth/2)), (int)(obj->dev_y + obj->dev_h + report->ypos - offset_break - (lwidth/2)) ); } else { RoundRect( hDC, (int)(obj->dev_x + report->dev_margin_left + 1 + (lwidth/2)), (int)(obj->dev_y + report->ypos - offset_break + 1 + (lwidth/2)), (int)(obj->dev_x + obj->dev_w + report->dev_margin_left - (lwidth/2)), (int)(obj->dev_y + obj->dev_h + report->ypos - offset_break - (lwidth/2)), 20, 20 ); } } SelectObject( hDC, GetStockObject(BLACK_PEN) ); SelectObject( hDC, GetStockObject(BLACK_BRUSH) ); if( hbrush ) DeleteObject( hbrush ); if( hpen ) DeleteObject( hpen ); len = 0; break; case obj4type_text: if( report->for_dbf ) { if( obj->field ) f4assign( obj->field, obj->wintext ); break; } output_ptr = obj->wintext; len = lstrlen( obj->wintext ); if( len > 0 ) { if( obj->style ) { if( report->output_code == 1 ) SelectObject( hDC, obj->style->screen_font ); else SelectObject( hDC, obj->style->printer_font ); SetTextColor( hDC, obj->style->color ); } rect.left = (int)(obj->dev_x + report->dev_margin_left); rect.top = (int)(obj->dev_y + report->ypos - offset_break); rect.right = rect.left + (int)obj->dev_w; rect.bottom = rect.top + (int)obj->dev_h; switch( obj->alignment ) { case justify4left: alignment = DT_LEFT; break; case justify4right: alignment = DT_RIGHT; break; case justify4center: alignment = DT_CENTER; break; } DrawText( hDC, output_ptr, (int)len, &rect, DT_WORDBREAK | alignment | DT_NOPREFIX ); } break; case obj4type_total: if( report->for_dbf ) { if( obj->field ) switch( ((PTOTAL4)obj->data)->total_type ) { case total4lowest: f4assign_double( obj->field, ((PTOTAL4)obj->data)->low ); break; case total4highest: f4assign_double( obj->field, ((PTOTAL4)obj->data)->high ); break; case total4count: f4assign_long( obj->field, ((PTOTAL4)obj->data)->count ); break; case total4sum: f4assign_double( obj->field, ((PTOTAL4)obj->data)->total ); break; case total4average: f4assign_double( obj->field, (((PTOTAL4)obj->data)->total/((PTOTAL4)obj->data)->count) ); break; } break; } case obj4type_expr: case obj4type_field: case obj4type_calc: if( report->for_dbf ) { if( !obj->lookahead ) obj4evaluate( obj ); if( obj->field ) switch( f4type(obj->field) ) { case r4str: case r4date: f4assign( obj->field, obj->eval_text ); break; case r4log: f4assign_char( obj->field, *(obj->eval_text) ); break; case r4num: f4assign_double( obj->field, obj->dval ); break; } break; } if( !obj->lookahead ) obj4evaluate( obj ); if( obj->eval_text ) { if( obj->style ) { if( report->output_code == 1 ) SelectObject( hDC, obj->style->screen_font ); else SelectObject( hDC, obj->style->printer_font ); SetTextColor( hDC, obj->style->color ); } rect.left = (int)(obj->dev_x + report->dev_margin_left); rect.top = (int)(obj->dev_y + report->ypos - offset_break); rect.right = rect.left + (int)obj->dev_w; rect.bottom = rect.top + (int)obj->dev_h; switch( obj->alignment ) { case justify4left: alignment = DT_LEFT; break; case justify4right: alignment = DT_RIGHT; break; case justify4center: alignment = DT_CENTER; break; } DrawText( hDC, obj->eval_text, obj->eval_len-1, &rect, DT_WORDBREAK | alignment | DT_NOPREFIX ); } break; #else case obj4type_text: if( report->for_dbf ) { if( obj->field ) f4assign( obj->field, obj->wintext ); break; } output_ptr = obj->wintext; break; case obj4type_total: if( obj->field && report->for_dbf ) { switch( ((PTOTAL4)obj->data)->total_type ) { case total4lowest: f4assign_double( obj->field, ((PTOTAL4)obj->data)->low ); break; case total4highest: f4assign_double( obj->field, ((PTOTAL4)obj->data)->high ); break; case total4count: f4assign_long( obj->field, ((PTOTAL4)obj->data)->count ); break; case total4sum: f4assign_double( obj->field, ((PTOTAL4)obj->data)->total ); break; } break; } case obj4type_expr: case obj4type_field: case obj4type_calc: if( report->for_dbf ) { if( !obj->lookahead ) obj4evaluate( obj ); if( obj->field ) switch( f4type(obj->field) ) { case r4str: case r4date: f4assign( obj->field, obj->eval_text ); break; case r4log: f4assign_char( obj->field, *(obj->eval_text) ); break; case r4num: f4assign_double( obj->field, obj->dval ); break; } break; } if( !obj->lookahead ) obj4evaluate( obj ); if( obj->eval_text ) output_ptr = obj->eval_text; else output_ptr = NULL; break; #endif } #ifndef S4WINDOWS file4seq_write( &hDC->seq_wr, &obj->obj_type_num, sizeof(short) ); obj_len = 5*sizeof(long) + 2*sizeof(short); switch( obj->obj_type_num ) { case obj4type_text: obj_len += strlen(obj->wintext); break; case obj4type_frame: obj_len += 2; break; case obj4type_hline: case obj4type_vline: break; default: obj_len += (obj->eval_len - 1); break; } file4seq_write( &hDC->seq_wr, &obj_len, sizeof(obj_len) ); lval = obj->dev_x + report->dev_margin_left; file4seq_write( &hDC->seq_wr, &lval, sizeof(lval) ); lval = obj->dev_y + report->ypos - offset_break; file4seq_write( &hDC->seq_wr, &lval, sizeof(lval) ); file4seq_write( &hDC->seq_wr, &obj->dev_w, sizeof(obj->dev_w) ); file4seq_write( &hDC->seq_wr, &obj->dev_h, sizeof(obj->dev_h) ); file4seq_write( &hDC->seq_wr, &obj->alignment, sizeof(obj->alignment) ); if( obj->style ) { file4seq_write( &hDC->seq_wr, &obj->style->position, sizeof(obj->style->position) ); } else { i = 0; file4seq_write( &hDC->seq_wr, &i, sizeof(short) ); } switch( obj->obj_type_num ) { case obj4type_text: data_len = strlen(obj->wintext); file4seq_write( &hDC->seq_wr, &data_len, sizeof(data_len) ); file4seq_write( &hDC->seq_wr, obj->wintext, (unsigned)data_len ); break; case obj4type_frame: data_len = 2; file4seq_write( &hDC->seq_wr, &data_len, sizeof(data_len) ); file4seq_write( &hDC->seq_wr, &obj->display_zero, 1 ); file4seq_write( &hDC->seq_wr, &obj->alignment, 1 ); break; case obj4type_hline: case obj4type_vline: data_len = 0; file4seq_write( &hDC->seq_wr, &data_len, sizeof(data_len) ); break; default: data_len = obj->eval_len - 1; file4seq_write( &hDC->seq_wr, &data_len, sizeof(data_len) ); file4seq_write( &hDC->seq_wr, obj->eval_text, (unsigned)data_len ); break; } #endif obj_on = (OBJ4 *)l4first( &obj->contained ); while( obj_on ) { #ifdef S4WINDOWS report4output_object( obj_on, hDC ); #else report4output_object( obj_on, hDC ); #endif obj_on = (OBJ4 *)l4next( &obj->contained, obj_on ); } return 0; } GROUP4 * S4FUNCTION report4calc_first_change_group( REPORT4 *report ) { GROUP4 *group_on, *change_group = NULL; char *ptr ; int len ; group_on = (GROUP4 *)l4first( &report->groups ); if( group_on->title_summary ) group_on = (GROUP4 *)l4next( &report->groups, group_on ); while( group_on ) { if( !group_on->reset_expression && !change_group ) change_group = group_on; if( group_on->reset_expression ) { len = expr4vary( group_on->reset_expression, &ptr ); if( memcmp(group_on->last_reset_value, ptr, len) != 0 && !change_group ) change_group = group_on; memcpy( group_on->last_reset_value, ptr, len ); } group_on = (GROUP4 *)l4next( &report->groups, group_on ); } return change_group; } int report4alloc_records( REPORT4 *report ) { RELATE4 *relate_on; if( !report ) { return -1; } if( report->code_base->error_code < 0 ) return -1; relate_on = &report->relate->relation->relate; while(relate_on) { if( !relate_on->old_record ) relate_on->old_record = (char *)u4alloc_free( report->code_base, relate_on->data->record_width + 1 ); if( relate_on->old_record == NULL ) { return -1; } relate4next(&relate_on); } return 0; } int report4make_old_rec( REPORT4 *report ) { RELATE4 *relate; if( !report ) { return -1; } if( report->code_base->error_code < 0 ) return -1; relate = &report->relate->relation->relate; while(relate) { memcpy(relate->old_record,relate->data->record,relate->data->record_width); relate4next(&relate); } return 0; } int report4swap_old_rec( REPORT4 *report ) { RELATE4 *relate_on; char *tempptr; int i; if( !report ) { return -1; } if( report->code_base->error_code < 0 ) return -1; relate_on = &report->relate->relation->relate; while (relate_on ) { tempptr = relate_on->data->record; relate_on->data->record = relate_on->old_record; relate_on->old_record = tempptr; if ( relate_on->data->fields_memo != 0 ) { for ( i = 0; i < relate_on->data->n_fields_memo ; i++ ) relate_on->data->fields_memo[i].status = 1; } relate4next(&relate_on); } return 0; } int report4output_area_break( AREA4 *area ) { int test, flag; OBJ4 *obj_on; if( !area->allow_pagebreaks ) return 0; test = (int)(area->report->disp_bottom - area->report->ypos + 1); flag = 0; if( area->report->break_height ) test += area->report->break_height; while( !flag && test > 0 ) { flag = 1; test--; obj_on = (OBJ4 *)l4first( &area->objects ); while( obj_on ) { if( test >= obj_on->dev_y && test <= obj_on->dev_y+obj_on->dev_h ) { flag = 0; test = (int)obj_on->dev_y; obj_on = NULL; } else obj_on = (OBJ4 *)l4next( &area->objects, obj_on ); } } return test; } #ifdef S4WINDOWS #ifdef __cplusplus void report4output_pgheader(REPORT4 *report, HDC hDC ) #else void report4output_pgheader(report, hDC ) REPORT4 *report ; HDC hDC ; #endif #else #ifdef __cplusplus void report4output_pgheader(REPORT4 *report, PAGE4 *hDC ) #else void report4output_pgheader(report, hDC ) REPORT4 *report ; PAGE4 *hDC ; #endif #endif { AREA4 *area_on; short broken; broken = report->broken; report->broken = 0; area_on = (AREA4 *)l4first( &report->page_header_footer->header_areas ); while( area_on ) { report4output_area( area_on, hDC, 1 ); area_on = (AREA4 *)l4next( &report->page_header_footer->header_areas, area_on ); } report->broken = broken; } #ifdef S4WINDOWS #ifdef __cplusplus void report4output_pgfooter(REPORT4 *report, HDC hDC ) #else void report4output_pgfooter(report, hDC ) REPORT4 *report ; HDC hDC ; #endif #else #ifdef __cplusplus void report4output_pgfooter(REPORT4 *report, PAGE4 *hDC ) #else void report4output_pgfooter(report, hDC ) REPORT4 *report ; PAGE4 *hDC ; #endif #endif { AREA4 *area_on; short broken; broken = report->broken; report->broken = 0; report->ypos = report->disp_bottom; area_on = (AREA4 *)l4first( &report->page_header_footer->footer_areas ); while( area_on ) { report4output_area( area_on, hDC, 1 ); area_on = (AREA4 *)l4next( &report->page_header_footer->footer_areas, area_on ); } report->broken = broken; } #ifdef S4WINDOWS #ifdef __cplusplus void report4output_repeat_headers(REPORT4 *report, HDC hDC, GROUP4 *group_first ) #else void report4output_repeat_headers(report, hDC, group_first ) REPORT4 *report ; HDC hDC ; GROUP4 *group_first ; #endif #else #ifdef __cplusplus void report4output_repeat_headers(REPORT4 *report, PAGE4 *hDC, GROUP4 *group_first ) #else void report4output_repeat_headers(report, hDC, group_first ) REPORT4 *report ; PAGE4 *hDC ; GROUP4 *group_first ; #endif #endif { GROUP4 *group_on; if( !report->first ) return; group_on = (GROUP4 *)l4first( &report->groups ); while( group_on != group_first ) { if( group_on->repeat_header ) report4output_group_headers( group_on, hDC, group_first, 0 ); group_on = (GROUP4 *)l4next( &report->groups, group_on ); } } #ifdef S4WINDOWS #ifdef __cplusplus void report4output_swapped_footer( GROUP4 *group, HDC hDC ) #else void report4output_swapped_footer(group, hDC ) GROUP4 *group ; HDC hDC ; #endif #else #ifdef __cplusplus void report4output_swapped_footer( GROUP4 *group, PAGE4 *hDC ) #else void report4output_swapped_footer(group, hDC ) GROUP4 *group ; PAGE4 *hDC ; #endif #endif { REPORT4 *report = group->report; AREA4 *area_on; OBJ4 *obj_on; int suppress; long theight; if( report->page_header_footer->footer_areas.n_link > 0 ) report->ypos = report->disp_bottom; else { theight = 0; area_on = (AREA4 *)l4first( &group->footer_areas ); while( area_on ) { if( !area_on->suppression_condition || expr4true(area_on->suppression_condition) ) theight += area_on->height_dev; area_on = (AREA4 *)l4next( &group->footer_areas, area_on ); } report->ypos = report->disp_bottom - theight; } area_on = (AREA4 *)l4first( &group->footer_areas ); while( area_on ) { suppress = 0; if( area_on->suppression_condition ) { suppress = expr4true( area_on->suppression_condition ); } if( suppress ) { area_on = (PAREA4)l4next( &group->footer_areas, area_on ); continue; } obj_on = (OBJ4 *)l4first( &area_on->objects ); while( obj_on ) { if( report->ypos + obj_on->dev_y + obj_on->dev_h < report->dev_page_height - report->dev_margin_bottom ) { report4output_object( obj_on, hDC ); } obj_on = (OBJ4 *)l4next( &area_on->objects, obj_on ); } report->ypos += area_on->height_dev; area_on = (AREA4 *)l4next( &group->footer_areas, area_on ); } } int S4FUNCTION report4pageInit( PREPORT4 report ) { int rc, i; int len; TOTAL4 *total_on; GROUP4 *group_on; char *ptr; PSTYLE4 style; #ifndef S4WINDOWS char name_buf[13]; int tsafety; #endif if( !report ) { return -1; } relate4skip_enable( report->relate, 1 ); #ifdef S4WINDOWS report->hWnd2 = 0; #ifdef S4WIN32 report->hWnd2 = CreateWindowEx( WS_EX_TRANSPARENT, "MouseEat", "EatInput", WS_POPUP | WS_CAPTION | WS_BORDER | WS_VISIBLE, 0, 0, 5, 5, report->hWnd, NULL, (HINSTANCE)GetWindowLong(report->hWnd, GWL_HINSTANCE), NULL ); #else report->hWnd2 = CreateWindowEx( WS_EX_TRANSPARENT, "MouseEat", "EatInput", WS_POPUP | WS_CAPTION | WS_BORDER | WS_VISIBLE, 0, 0, 5, 5, report->hWnd, NULL, (HINSTANCE)GetWindowWord(report->hWnd, GWW_HINSTANCE), NULL ); #endif if( report->hWnd2 ) { #ifdef S4WIN32 SetClassLong( report->hWnd2, GCL_HCURSOR, 0L ); #else SetClassWord( report->hWnd2, GCW_HCURSOR, 0 ); #endif SetCursor( LoadCursor(NULL,IDC_WAIT) ); SetCapture( report->hWnd2 ); } #endif rc = relate4top( report->relate ); switch( rc ) { case r4terminate: case r4locked: case r4eof: break; } if( rc < 0 ) return -1; report->tdone = 0; report->page_no = report->page_count = 0; if( (report4alloc_records( report )) < 0 ) return -1; i = 0; style = (PSTYLE4)l4first( &report->styles ); while( style ) { style->position = i; i++; style = (PSTYLE4)l4next( &report->styles, style ); } group_on = (GROUP4 *)l4first( &report->groups ); while( group_on ) { if( group_on->title_summary ) group_on->tsdone = 0; group_on->reset_flag = 0; if( group_on->last_reset_value ) { u4free( group_on->last_reset_value ); group_on->last_reset_value = NULL; } if( group_on->reset_expression ) { len = expr4vary( group_on->reset_expression, &ptr ); group_on->last_reset_value = (char *)u4alloc_free( report->code_base, len + 1 ); if( group_on->last_reset_value ) memcpy( group_on->last_reset_value, ptr, len ); } group_on = (GROUP4 *)l4next( &report->groups, group_on ); } total_on = (TOTAL4 *)l4first( &report->code_base->total_list ); while( total_on ) { if( total_on->last_add_value ) { u4free( total_on->last_add_value ); total_on->last_add_value = NULL; } if( total_on->add_condition ) { total_on->last_add_value = (char *)u4alloc_free( report->code_base, expr4len(total_on->add_condition)+1 ); } total_on->donce = 0; if( total_on->last_reset_value ) { u4free( total_on->last_reset_value ); total_on->last_reset_value = NULL; } if( total_on->reset_expression ) { total_on->last_reset_value = (char *)u4alloc_free( report->code_base, expr4len(total_on->reset_expression)+1 ); } total_on = (TOTAL4 *)l4next( &report->code_base->total_list, total_on ); } report4check_lookahead( report ); report4check_display_once( report ); report->group_on = (GROUP4 *)l4first( &report->groups ); report->group_first = NULL; report->area_on = NULL; report->in_header = 1; report->end_report = 0; report->code_base->pageno = 0; report->first = 0; total_on = (TOTAL4 *) l4first( &report->code_base->total_list ); while( total_on ) { total4value_reset( total_on ); total_on = (TOTAL4 *) l4next( &report->code_base->total_list, total_on ); } #ifndef S4WINDOWS report4calc_obj_dev( report ); report->dev_page_width = report->report_width + report->margin_right + report->margin_left; report->dev_page_height = report->report_height + report->margin_top + report->margin_bottom; if( report->output_handle > 0 ) { tsafety = report->code_base->safety; report->code_base->safety = 0; if( !report->report_file_name || *report->report_file_name =='\0' ) strcpy( name_buf, "crep2.buf" ); else { u4name_piece( name_buf, sizeof(name_buf), report->report_file_name, 0, 1 ); u4name_ext( name_buf, sizeof(name_buf), "buf", 1 ); } if( file4create( &report->page_buf.file_buf, report->code_base, name_buf, 1 ) < 0 ) { e4describe( report->code_base, e4rep_out, E4_REP_PFILE, 0, 0 ); return -1; } report->code_base->safety = tsafety; file4seq_write_init( &report->page_buf.seq_wr, &report->page_buf.file_buf, 0L, report->page_buf.fmem_buf, sizeof(report->page_buf.fmem_buf) ); } #endif return 0; } int S4FUNCTION report4pageFree( PREPORT4 report ) { char name_buf[512]; if( !report ) { return -1; } if( report->page_buf.object.info != NULL ) { u4free( report->page_buf.object.info ); report->page_buf.object.info = NULL; report->page_buf.object.info_len = 0; } if( report->page_buf.mem_buf != NULL ) { u4free( report->page_buf.mem_buf ); report->page_buf.mem_buf = NULL; } if( report->page_buf.file_buf.name != NULL ) { strcpy( name_buf, report->page_buf.file_buf.name ); file4close( &report->page_buf.file_buf ); u4remove( name_buf ); } report->page_buf.info_buf_len = 0; return 0; } POBJECT4 S4FUNCTION report4pageObjNext( PREPORT4 report ) { long obj_size; POBJECT4 object; FILE4SEQ_READ *file_buf; if( !report ) { return NULL; } if( report->page_buf.file_buf.name == NULL ) { e4describe( report->code_base, e4rep_out, E4_REP_NOBUFPAGE, (char *)0, (char *)0 ); return NULL; } if( !report->page_buf.first_read ) file4seq_read_init( &report->page_buf.seq_rd, &report->page_buf.file_buf, 0L, report->page_buf.rmem_buf, sizeof(report->page_buf.rmem_buf) ); file_buf = &report->page_buf.seq_rd; object = &report->page_buf.object; if( (file4seq_read( file_buf, &object->objtype, sizeof( object->objtype) )) == 0 ) return NULL; file4seq_read( file_buf, &obj_size, sizeof(obj_size) ); file4seq_read( file_buf, &object->x, sizeof(object->x) ); file4seq_read( file_buf, &object->y, sizeof(object->y) ); file4seq_read( file_buf, &object->w, sizeof(object->w) ); file4seq_read( file_buf, &object->h, sizeof(object->h) ); file4seq_read( file_buf, &object->alignment, sizeof(object->alignment) ); file4seq_read( file_buf, &object->style_index, sizeof(object->style_index) ); file4seq_read( file_buf, &object->info_len, sizeof(object->info_len) ); if( report->page_buf.info_buf_len < object->info_len ) { if( object->info != NULL ) { u4free( object->info ); object->info = NULL; } object->info = (char *)u4alloc_free( report->code_base, object->info_len+1 ); if( !object->info ) { e4describe( report->code_base, e4rep_out, E4_REP_OBJDATAAL, (char *)0, (char *)0 ); return NULL; } memset( object->info, 0, (int)report->page_buf.info_buf_len ); report->page_buf.info_buf_len = object->info_len + 1; if( object->info_len > 0 ) file4seq_read( file_buf, object->info, (unsigned)object->info_len ); } else { memset( object->info, 0, (int)report->page_buf.info_buf_len ); if( object->info_len > 0 ) file4seq_read( file_buf, object->info, (unsigned)object->info_len ); } return object; } POBJECT4 S4FUNCTION report4pageObjFirst( PREPORT4 report ) { if( !report ) { return NULL; } if( report->page_buf.file_buf.name == NULL ) { e4describe( report->code_base, e4rep_out, E4_REP_NOBUFPAGE, (char *)0, (char *)0 ); return NULL; } file4seq_read_init( &report->page_buf.seq_rd, &report->page_buf.file_buf, 0L, report->page_buf.rmem_buf, sizeof(report->page_buf.rmem_buf) ); report->page_buf.first_read = 1; return report4pageObjNext( report ); } #ifndef S4WINDOWS void r4place_text( OBJECT4 *object, char *buffer, int lw, char *sbuffer ) { int ox, oy, oh, ow, lc; int offset, length; char *pbuf, *line, *sbuf, *bpt; ox = (int)(((float)object->x/100.0)+0.5); oy = (int)(((float)object->y/1000.0)*6.0+0.5); oh = (int)(((float)object->h/1000.0)*6.0+0.5); ow = (int)(((float)object->w/100.0)+0.5); pbuf = (buffer + ox + oy * lw ); if( sbuffer ) sbuf = (sbuffer + ox + oy * lw ); if( oh == 1 ) { if( ow >= object->info_len && ox + ow <= lw ) { offset = 0; if( object->alignment == justify4right ) offset = ow - (int)object->info_len; if( object->alignment == justify4center ) offset = (ow - (int)object->info_len)/2; memcpy( pbuf + offset, object->info, (int)object->info_len ); if( sbuffer ) memset( sbuf + offset, object->style_index, (int)object->info_len ); return; } else { if( ox + ow <= lw ) length = ow; else length = lw - ox; memcpy( pbuf, object->info, length ); if( sbuffer ) memset( sbuf, object->style_index, length ); } } else { lc = length = 0; if( ox + ow <= lw ) length = ow; else length = lw - ox; line = strtok( (char *)object->info, "\r\n" ); while( line && lc < oh ) { if( strlen(line) > (unsigned)length ) { while( strlen(line) > (unsigned)length && lc < oh ) { bpt = line + length; while( bpt != line && *bpt != ' ' ) bpt--; if( bpt == line ) bpt = line + length; memcpy( pbuf, line, (bpt-line) ); if( sbuffer ) { memset( sbuf, object->style_index, (bpt-line) ); sbuf += lw; } lc++; line += (bpt-line); if( *line == ' ' ) line++; pbuf += lw; } memcpy( pbuf, line, strlen(line) ); if( sbuffer ) { memset( sbuf, object->style_index, strlen(line) ); sbuf += lw; } pbuf += lw; lc++; } else { offset = 0; if( object->alignment == justify4right ) offset = length - strlen(line); if( object->alignment == justify4center ) offset = (length - strlen(line))/2; memcpy( pbuf + offset, line, strlen(line) ); if( sbuffer ) { memset( sbuf + offset, object->style_index, strlen(line) ); sbuf += lw; } lc++; pbuf += lw; } line = strtok( NULL, "\r\n" ); } } } int report4output_general_dos( PREPORT4 report ) { OBJECT4 *object; char *page_buf=NULL, *style_buf=NULL; int ph, pw, old_style, new_style, offset; long lpw, lph, i, j; PSTYLE4 style; report4pageSizeGet( report, &lpw, &lph ); pw = (int)(((float)lpw/100.0)+0.5); ph = (int)(((float)lph/1000.0)*6.0+0.5); page_buf = (char *)u4alloc_free( report->code_base, (pw*ph) ); if( !page_buf ) { return -1; } if( report->use_styles ) { style_buf = (char *)u4alloc_free( report->code_base, (pw*ph) ); if( !style_buf ) return -1; memset( style_buf, 0, (pw*ph) ); } memset( page_buf, ' ', (pw*ph) ); object = report4pageObjFirst( report ); while( object ) { switch( object->objtype ) { case obj4type_field: case obj4type_expr: case obj4type_total: case obj4type_calc: case obj4type_text: if( report->use_styles ) r4place_text( object, page_buf, pw, style_buf ); else r4place_text( object, page_buf, pw, NULL ); break; } object = report4pageObjNext( report ); } style = NULL; old_style = 0; for( i = 0; i < ph; i++ ) { for( j = 0; j < pw; j++ ) { if( report->use_styles ) { offset = (int)(i*pw + j); #ifdef S4UNIX memcpy( &new_style, style_buf+offset, sizeof(new_style) ) ; #else new_style = (int)(*(style_buf+offset)); #endif if( new_style != old_style ) { if( style ) write( report->output_handle, style->codes_after, style->codes_after_len ); style = style4index( report, new_style ); if( style ) write( report->output_handle, style->codes_before, style->codes_before_len ); old_style = new_style; } } write( report->output_handle, page_buf + (i*pw) + j, 1 ); } if( i < ph - 1 ) write( report->output_handle, "\r\n", 2 ); } if( style ) write( report->output_handle, style->codes_after, style->codes_after_len ); write( report->output_handle, "\f", 1 ); if( page_buf ) u4free( page_buf ); if( style_buf ) u4free( style_buf ); return 0; } int report4output_screen_dos( PREPORT4 report ) { OBJECT4 *object; char *page_buf=NULL; int i, ph, pw; pw = (int)(((float)report->dev_page_width/100.0)+0.5); ph = (int)(((float)report->dev_page_height/1000.0)*6.0+0.5); page_buf = (char *)u4alloc_free( report->code_base, (pw*ph) ); if( !page_buf ) { return -1; } memset( page_buf, ' ', (pw*ph) ); object = report4pageObjFirst( report ); while( object ) { switch( object->objtype ) { case obj4type_field: case obj4type_expr: case obj4type_total: case obj4type_calc: case obj4type_text: r4place_text( object, page_buf, pw, NULL ); break; } object = report4pageObjNext( report ); } for( i = 0; i < ph; i++ ) { write( 1, page_buf+(i*pw), pw-1 ); if( i < ph-1 ) write( 1, "\r\n", 2 ); } #ifdef S4UNIX if( getchar() == 0x1b ) #else #ifndef S4PASCAL_DOS if( getch() == 0x1b ) #endif #endif return -1; write( 1, "\r\n", 2 ); if( page_buf ) u4free( page_buf ); return 0; } int S4FUNCTION report4do( REPORT4 *report ) { int rc; if( report4pageInit( report ) < 0 ) return -1; while( (rc = report4generatePage( report )) >= 0 ) { if( rc == 2 ) break; if( report->output_handle == 1 ) { if( report4output_screen_dos( report ) < 0 ) break; } else if( report->output_handle > 1 ) { if( report4output_general_dos( report ) < 0 ) break; } } report4pageFree( report ); return 0; } #endif