void clear_doc_element( doc_element * element ) { doc_element * cur_el; text_line * cur_line; text_line * save; for( cur_el = element; cur_el != NULL; cur_el = cur_el->next ) { switch( cur_el->type ) { case el_binc : case el_dbox : case el_graph : case el_hline : case el_vline : break; // should be nothing to do case el_text : cur_line = cur_el->element.text.first; while( cur_line != NULL ) { add_text_chars_to_pool( cur_line ); save = cur_line->next; add_text_line_to_pool( cur_line ); cur_line = save; } break; default : internal_err( __FILE__, __LINE__ ); } } return; }
void insert_page_width( doc_element * a_element ) { uint32_t depth; /* depth is used to update t_page.cur_depth and so must be kept separate */ if( !ProcFlags.page_started ) { depth = a_element->top_skip; ProcFlags.page_started = true; } else { depth = a_element->subs_skip; } depth += a_element->depth; /****************************************************************/ /* Does the first line minimum apply here? If so, it needs to */ /* be implemented. Note that cur_el->depth does not reflect it */ /* because there is no way to tell if it will apply when the */ /* is computed. */ /****************************************************************/ switch( a_element->type ) { // TOP FIG processing goes here case el_text : // section heading: must go on t_page if( (depth + t_page.cur_depth) <= t_page.max_depth ) { if( t_page.page_width == NULL ) { // must be empty t_page.page_width = a_element; t_page.last_col_main = t_page.page_width; t_page.cur_depth += depth; if( bin_driver->y_positive == 0 ) { t_page.main_top -= depth; } else { t_page.main_top += depth; } } else { // discard second section heading internal_err( __FILE__, __LINE__ ); } } else { xx_err( err_heading_too_deep ); } break; default: internal_err( __FILE__, __LINE__ ); } return; }
doc_element * alloc_doc_el( element_type type ) { doc_element * curr; doc_element * prev; int k; curr = doc_el_pool; if( curr != NULL ) { // there is one to use doc_el_pool = curr->next; } else { // pool is empty curr = mem_alloc( sizeof( doc_element ) ); doc_el_pool = mem_alloc( sizeof( *prev ) ); prev = doc_el_pool; for( k = 0; k < 10; k++ ) { // alloc 10 doc_els if pool empty prev->next = mem_alloc( sizeof( *prev ) ); prev = prev->next; } prev->next = NULL; } curr->next = NULL; curr->blank_lines = 0; curr->depth = 0; curr->subs_skip = 0; curr->top_skip = 0; curr->type = type; switch( type ) { case el_binc : curr->element.binc.cur_left = 0; curr->element.binc.depth = 0; curr->element.binc.y_address = 0; curr->element.binc.at_top = false; curr->element.binc.has_rec_type = false; curr->element.binc.file[0] = '\0'; break; case el_graph : curr->element.graph.cur_left = 0; curr->element.graph.depth = 0; curr->element.graph.scale = 0; curr->element.graph.width = 0; curr->element.graph.y_address = 0; curr->element.graph.xoff = 0; curr->element.graph.yoff = 0; curr->element.graph.at_top = false; curr->element.graph.file[0] = '\0'; break; case el_text : curr->element.text.overprint = false; curr->element.text.spacing = 0; curr->element.text.first = NULL; break; default : internal_err( __FILE__, __LINE__ ); } return( curr ); }
void gml_ul( const gmltag * entry ) { bool compact; char * p; ul_lay_level * ul_layout = NULL; p = scan_start + 1; while( *p == ' ' ) { p++; } scan_start = p; // over spaces if( !strnicmp( "compact", p, 7 ) ) { compact = true; scan_start = p + 7; } else { compact = false; } if( ProcFlags.need_li_lp ) { xx_nest_err( err_no_li_lp ); } gml_xl_lp_common( t_UL ); ul_layout = layout_work.ul.first; while( (ul_layout != NULL) && (ul_cur_level < ul_layout->level) ) { ul_layout = ul_layout->next; } if( ul_layout == NULL ) { internal_err( __FILE__, __LINE__ ); } if( ul_cur_level < layout_work.ul.max_level ) { ul_cur_level++; } else { ul_cur_level = 1; } nest_cb->compact = compact; nest_cb->li_number = 0; nest_cb->left_indent = conv_hor_unit( &ul_layout->left_indent, g_curr_font ) + nest_cb->prev->left_indent + nest_cb->prev->align; nest_cb->right_indent = -1 * conv_hor_unit( &ul_layout->right_indent, g_curr_font ) + nest_cb->prev->right_indent; nest_cb->xl_pre_skip = ul_layout->pre_skip; nest_cb->lay_tag = ul_layout; nest_cb->lm = g_cur_left; nest_cb->rm = g_page_right; spacing = (int8_t) ul_layout->spacing; scan_start = scan_stop + 1; return; }
void gml_gl( const gmltag * entry ) // not tested TBD { bool compact; char * p; gl_lay_level * gl_layout = NULL; p = scan_start; p++; while( *p == ' ' ) { p++; } scan_start = p; // over spaces if( !strnicmp( "compact", p, 7 ) ) { compact = true; scan_start = p + 7; } else { compact = false; } gml_xl_lp_common( t_GL ); gl_layout = layout_work.gl.first; while( (gl_layout != NULL) && (gl_cur_level < gl_layout->level) ) { gl_layout = gl_layout->next; } if( gl_layout == NULL ) { internal_err( __FILE__, __LINE__ ); } if( gl_cur_level < layout_work.gl.max_level ) { gl_cur_level++; } else { gl_cur_level = 1; } nest_cb->compact = compact; nest_cb->li_number = 0; nest_cb->align = conv_hor_unit( &gl_layout->align, g_curr_font ); nest_cb->left_indent = conv_hor_unit( &gl_layout->left_indent, g_curr_font ) + nest_cb->prev->left_indent + nest_cb->prev->align; nest_cb->right_indent = -1 * conv_hor_unit( &gl_layout->right_indent, g_curr_font ) + nest_cb->prev->right_indent; nest_cb->xl_pre_skip = gl_layout->pre_skip; nest_cb->lay_tag = gl_layout; nest_cb->lm = g_cur_left; nest_cb->rm = g_page_right; spacing = (int8_t) gl_layout->spacing; scan_start = scan_stop + 1; return; }
// Return the type signature for the ideal operation const char *ArchDesc::getIdealType(const char *idealOp) { // Find last character in idealOp, it specifies the type char last_char = 0; const char *ptr = idealOp; for (; *ptr != '\0'; ++ptr) { last_char = *ptr; } // Match Vector types. if (strncmp(idealOp, "Vec",3)==0) { switch(last_char) { case 'S': return "TypeVect::VECTS"; case 'D': return "TypeVect::VECTD"; case 'X': return "TypeVect::VECTX"; case 'Y': return "TypeVect::VECTY"; case 'Z': return "TypeVect::VECTZ"; default: internal_err("Vector type %s with unrecognized type\n",idealOp); } } // !!!!! switch(last_char) { case 'I': return "TypeInt::INT"; case 'P': return "TypePtr::BOTTOM"; case 'N': return "TypeNarrowOop::BOTTOM"; case 'F': return "Type::FLOAT"; case 'D': return "Type::DOUBLE"; case 'L': return "TypeLong::LONG"; case 's': return "TypeInt::CC /*flags*/"; default: return NULL; // !!!!! // internal_err("Ideal type %s with unrecognized type\n",idealOp); break; } return NULL; }
char * get_member_name( char const * in_name ) { char * member_name = NULL; cop_file_type file_type; directory_entry current_entry; entry_found entry_status; size_t member_length; uint16_t entry_type; /* See if in_name is found in try_file_name. */ file_type = parse_header( try_fp ); switch( file_type ) { case file_error: /* File error, including premature eof. */ xx_simple_err_c( err_dev_lib_file, try_file_name ); break; case not_se_v4_1: /* File was created by a different version of gendev. */ xx_simple_err( err_wrong_gendev ); break; case not_bin_dev: case se_v4_1_not_dir: /* Wrong type of file: something is wrong with the device library. */ xx_simple_err_c( err_dev_lib_data, try_file_name ); break; case dir_v4_1_se: /* try_fp was a same-endian version 4.1 directory file. */ /* Skip the number of entries. */ fseek( try_fp, sizeof( uint32_t ), SEEK_CUR ); if( ferror( try_fp ) || feof( try_fp ) ) { break; } for( ;; ) { /* Get the entry_type. This is either the type or the metatype, * depending on whether this is a CompactDirEntry or an * ExtendedDirEntry. */ entry_type = fread_u16( try_fp ); /* Exit the loop when the final entry has been processed. */ if( feof( try_fp ) || ferror( try_fp ) ) { break; } switch( entry_type) { case 0x0000: /* This should only happen when the end-of-file padding is * reached, but continue in case there is more data. */ continue; case 0x0001: /* This will be an ExtendedDirEntry. */ for( ;; ) { /* Get the entry_type. This is always the type, since the * metatype has already been read. */ entry_type = fread_u16( try_fp ); /* Exit the loop when the final entry has been processed. */ if( feof( try_fp ) || ferror( try_fp ) ) { break; } switch( entry_type ) { case 0x0000: /* This should only happen when the end-of-file padding is * reached, but continue in case there is more data. */ continue; case 0x0001: /* This should never actually occur; however, continue * in case there is more data. */ continue; case 0x0101: case 0x0201: case 0x0401: /* For any type, check the defined name. */ entry_status = get_extended_entry( try_fp, ¤t_entry ); switch( entry_status ) { case valid_entry: /* Return the member name, if found. */ if( !stricmp( in_name, current_entry.defined_name ) ) { member_length = strlen( current_entry.member_name ) + 1; member_name = mem_alloc( member_length ); strcpy( member_name, current_entry.member_name ); return( member_name ); } break; case not_valid_entry: break; default: /* The entry_status is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } break; default: /* The entry_type is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } break; } break; case 0x0101: case 0x0201: case 0x0401: /* For any type, check the defined name. */ entry_status = get_compact_entry( try_fp, ¤t_entry ); switch( entry_status ) { case valid_entry: /* Return the member name, if found. */ if( !stricmp( in_name, current_entry.defined_name) ) { member_length = strlen( current_entry.member_name ) + 1; member_name = mem_alloc( member_length ); strcpy( member_name, current_entry.member_name ); return( member_name ); } break; case not_valid_entry: break; default: /* The entry_status is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } break; default: /* The entry_type is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } } break; default: /* The file_type is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } return( member_name ); }
static void do_el_list_out( doc_element * array, uint8_t count ) { doc_element * cur_el; doc_element * save; int i; text_line * cur_line; /* Advise the user that multiple columns are not, in fact, implemented */ if( count > 1 ) { out_msg( "Multi-column output not implemented" ); } /* The array should have the doc_elements in linked-list form in the */ /* same order as the columns they came from were linked together. */ /* The columns should no longer point to these doc_element lists. */ for( i = 0; i < count; i++ ) { cur_el = &array[i]; while( cur_el != NULL ) { if( i == 0 ) { // restrict output to first column, for now switch( cur_el->type ) { case el_binc : if( GlobalFlags.lastpass ) { ob_binclude( &cur_el->element.binc ); } break; case el_dbox : // should only be found if DBOX block exists if( GlobalFlags.lastpass ) { fb_dbox( &cur_el->element.dbox ); } break; case el_graph : if( GlobalFlags.lastpass ) { if( ProcFlags.ps_device ) { // only available to PS device ob_graphic( &cur_el->element.graph ); } } break; case el_hline : // should only be found if HLINE block exists if( GlobalFlags.lastpass ) { fb_hline( &cur_el->element.hline ); } break; case el_text : if( GlobalFlags.lastpass ) { for( cur_line = cur_el->element.text.first; cur_line != NULL; cur_line = cur_line ->next ) { fb_output_textline( cur_line ); } } break; case el_vline : // should only be found if VLINE block exists if( GlobalFlags.lastpass ) { fb_vline( &cur_el->element.vline ); } break; default : internal_err( __FILE__, __LINE__ ); } } save = cur_el->next; cur_el->next = NULL; // clear only current element clear_doc_element( cur_el ); add_doc_el_to_pool( cur_el ); cur_el = save; } } return; }
static void update_t_page( void ) { bool fig_placed; bool splittable; doc_element * cur_el; uint32_t depth; reset_t_page(); /* some section headings are placed in t_page.page_width when */ /* processed. One FIG in n_page.col_top goes into t_page.page_width */ /* if it is empty */ /* t_page.page_width can only hold one doc_element */ /* This is preliminary and may be changed as needed. */ depth = t_page.cur_depth; fig_placed = false; if( t_page.page_width == NULL ) { // skip if section full if( n_page.col_top != NULL ) { // at most one item can be placed switch( n_page.col_top->type ) { // add code for FIG when needed case el_text : // all elements should be FIGs default : internal_err( __FILE__, __LINE__ ); } } } /* one FIG in n_page.col_top goes into t_page.main->top_fig if none */ /* was placed in t_page.page_width */ /* this is preliminary and may be changed as needed */ /* Note: t_page.main is NULL at this point, initialize if needed */ if( !fig_placed ) { if( n_page.col_top != NULL ) { // at most one item can be placed switch( n_page.col_top->type ) { // add code for FIG when needed case el_text : // all elements should be FIGs default : internal_err( __FILE__, __LINE__ ); } } } /***********************************************************************/ /* The order here is not clear. */ /* That shown is based on filling the t_page.main->bot_fig and the */ /* t_page.main->footnote parts before filling t_page.main->main, thus */ /* having a firm depth for t_page.main->main to start with. */ /* However, if there is no top_fig, then the first doc_element in */ /* t_page.main->main must set its pre_skip to 0, and then what */ /* happens if there is no room for anything to be placed there? */ /* So this may need to be rethought when FN and FIG are implemented. */ /***********************************************************************/ /* one FIG in n_page.col_bot goes into t_page.main->bot_fig */ /* entrained footnotes need to be moved to n_page.col_fn */ /* this is preliminary and may be changed as needed */ /* Note: t_page.main may be NULL at this point, initialize if needed */ if( n_page.col_bot != NULL ) { // at most one item can be placed switch( n_page.col_bot->type ) { // add code for FIG & entrained footnotes when needed case el_text : // all elements should be FIGs or footnotes default : internal_err( __FILE__, __LINE__ ); } } /* all footnotes in n_page.col_fn go into t_page.main->footnote */ /* this is preliminary and may be changed as needed */ /* Note: t_page.main may be NULL at this point, initialize if needed */ if( n_page.col_fn != NULL ) { // at most one item can be placed switch( n_page.col_fn->type ) { // add code for footnotes when needed case el_text : // all elements should be footnotes default : internal_err( __FILE__, __LINE__ ); } } /* t_page.main->main is used for the bulk of the elements */ /* it is filled last because the other deferred items are believed to */ /* have priority; this may change as the situation is clarified. */ /* unless the section is ended, there must be at least on element left */ /* in n_page.col_main for the page to be full */ /* Note: when FIG/FN processing is implemented, t_page.main may not be */ /* NULL at this point */ /****************************************************************/ /* test version until things get a bit more clear */ /* the theory here is that only one processing step should be */ /* here, and then the function calling update_t_page() */ /* should be relied on to output the page */ /****************************************************************/ while( n_page.col_main != NULL ) { cur_el = n_page.col_main; n_page.col_main = n_page.col_main->next; if( n_page.col_main == NULL ) { n_page.last_col_main = NULL; } /****************************************************************/ /* this section identifies skips and blank lines that finish */ /* the current page and then exits the loop after adjusting */ /* the element field values as needed */ /****************************************************************/ if( cur_el->blank_lines > 0 ) { if( (t_page.cur_depth + cur_el->blank_lines) >= t_page.max_depth ) { cur_el->blank_lines -= (t_page.max_depth - t_page.cur_depth); break; } else if( !ProcFlags.page_started && ((t_page.cur_depth + cur_el->blank_lines + cur_el->top_skip) >= t_page.max_depth) ) { cur_el->top_skip -= (t_page.max_depth - t_page.cur_depth); cur_el->top_skip += cur_el->blank_lines; cur_el->blank_lines = 0; break; } else if( (t_page.cur_depth + cur_el->blank_lines + cur_el->subs_skip) >= t_page.max_depth ) { cur_el->blank_lines = 0; break; } } if( !ProcFlags.page_started ) { if( cur_el->blank_lines > 0 ) { depth += cur_el->blank_lines + cur_el->subs_skip; } else { depth += cur_el->top_skip; } ProcFlags.page_started = true; } else { depth += cur_el->blank_lines + cur_el->subs_skip; } if( depth >= t_page.max_depth ) { // skip fills page break; } /****************************************************************/ /* Does the first line minimum apply here? If so, it needs to */ /* be implemented. Note that cur_el->depth does not reflect it */ /* because there is no way to tell if it will apply when the */ /* cur_el->depth is computed. */ /****************************************************************/ if( (depth + cur_el->depth) > t_page.max_depth ) { // cur_el will fill the page splittable = split_element( cur_el, t_page.max_depth - t_page.cur_depth - depth ); if( splittable ) { if( cur_el->next != NULL ) { // cur_el was split n_page.col_main = cur_el->next; if( n_page.last_col_main == NULL ) { n_page.last_col_main = n_page.col_main; } cur_el->next = NULL; } if( t_page.main == NULL ) { t_page.main = alloc_doc_col(); } if( t_page.main->main == NULL ) { t_page.main->main = cur_el; t_page.last_col_main = t_page.main->main; } else { t_page.last_col_main->next = cur_el; t_page.last_col_main = t_page.last_col_main->next; } t_page.last_col_main->next = NULL; t_page.cur_depth += cur_el->depth; } else { if( (t_page.main == NULL) || (t_page.main->main == NULL) ) { // adapt when FIG/FN done xx_err( err_text_line_too_deep ); g_suicide(); // no line will fit on any page } n_page.col_main = cur_el->next; if( n_page.last_col_main == NULL ) { n_page.last_col_main = n_page.col_main; } cur_el->next = NULL; } } else { // cur_el fits as-is if( t_page.main == NULL ) { t_page.main = alloc_doc_col(); } if( t_page.main->main == NULL ) { t_page.main->main = cur_el; t_page.last_col_main = t_page.main->main; } else { t_page.last_col_main->next = cur_el; t_page.last_col_main = t_page.last_col_main->next; } t_page.last_col_main->next = NULL; t_page.cur_depth += cur_el->depth; } } return; }
static void set_v_positions( doc_element * list, uint32_t v_start ) { doc_element * cur_el; text_line * cur_line; uint32_t cur_spacing; g_cur_v_start = v_start; for( cur_el = list; cur_el != NULL; cur_el = cur_el->next ) { cur_spacing = cur_el->blank_lines; if( cur_el->type == el_text ) { cur_spacing += cur_el->element.text.spacing; } if( !ProcFlags.page_started ) { if( cur_el->blank_lines > 0 ) { cur_spacing = cur_el->blank_lines + cur_el->subs_skip; } else { cur_spacing = cur_el->top_skip; } ProcFlags.page_started = true; } else { cur_spacing += cur_el->subs_skip; } switch( cur_el->type ) { case el_binc : cur_el->element.binc.at_top = !ProcFlags.page_started && (t_page.top_banner == NULL); if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_spacing; } else { g_cur_v_start += cur_spacing; } cur_el->element.binc.y_address = g_cur_v_start; if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_el->depth; } else { g_cur_v_start += cur_el->depth; } break; case el_dbox : if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_spacing; } else { g_cur_v_start += cur_spacing; } cur_el->element.dbox.v_start = g_cur_v_start; if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_el->depth; } else { g_cur_v_start += cur_el->depth; } break; case el_graph : cur_el->element.graph.at_top = !ProcFlags.page_started && (t_page.top_banner == NULL); if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_spacing; } else { g_cur_v_start += cur_spacing; } cur_el->element.graph.y_address = g_cur_v_start; if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_el->depth; } else { g_cur_v_start += cur_el->depth; } break; case el_hline : if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_spacing; } else { g_cur_v_start += cur_spacing; } cur_el->element.hline.v_start = g_cur_v_start; if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_el->depth; } else { g_cur_v_start += cur_el->depth; } break; case el_text : for( cur_line = cur_el->element.text.first; cur_line != NULL; cur_line = cur_line->next ) { cur_spacing += cur_line->line_height; if( ProcFlags.page_started ) { // not first element if( cur_el->element.text.overprint ) { cur_spacing -= cur_line->line_height; // overprint cur_el->element.text.overprint = false; } } else { if( t_page.top_ban == NULL ) { // minimun height if( cur_spacing < wgml_fonts[g_curr_font].line_height ) { cur_spacing = wgml_fonts[g_curr_font].line_height; } } } if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_spacing; } else { g_cur_v_start += cur_spacing; } cur_line->y_address = g_cur_v_start; cur_spacing = cur_el->element.text.spacing; } break; case el_vline : if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_spacing; } else { g_cur_v_start += cur_spacing; } cur_el->element.vline.v_start = g_cur_v_start; if( bin_driver->y_positive == 0x00 ) { g_cur_v_start -= cur_el->depth; } else { g_cur_v_start += cur_el->depth; } break; default : internal_err( __FILE__, __LINE__ ); } } return; }
bool split_element( doc_element * a_element, uint32_t req_depth ) { bool splittable; doc_element * split_el; text_line * cur_line; text_line * last; uint32_t count; uint32_t cur_depth; count = 0; cur_depth = 0; last = NULL; splittable = true; switch( a_element->type ) { // add code for other element types; FIGs are documented to split only // when they will not fit by themselves on a page case el_binc : // given how BINCLUDE/GRAPHIC work, this seems reasonable case el_dbox : // splitting boxes/lines is probably best done elsewhere case el_graph : case el_hline : case el_vline : splittable = false; break; case el_text : for( cur_line = a_element->element.text.first; cur_line != NULL; cur_line = cur_line->next ) { if( (cur_depth + cur_line->line_height) > req_depth ) { break; } count++; cur_depth += cur_line->line_height; last = cur_line; } if( cur_line != NULL ) { // at least one more line if( count < g_cur_threshold ) { splittable = false; // widow criteria failed a_element->blank_lines = 0; break; } } if( last == NULL ) { // all lines fit; unlikely, but seen break; } /* if we get here, a_element is splittable, cur_line is */ /* the first line of the new element, and last is the last */ /* line that can be left in the original element */ split_el = alloc_doc_el( el_text ); // most defaults are correct split_el->depth = a_element->depth - cur_depth; split_el->element.text.first = cur_line; last->next = NULL; a_element->depth = cur_depth; if( a_element->next == NULL ) { a_element->next = split_el; } else { split_el->next = a_element->next; a_element->next = split_el; } break; default : internal_err( __FILE__, __LINE__ ); } return( splittable ); }
doc_element * alloc_doc_el( element_type type ) { doc_element * curr; int k; if( doc_el_pool == NULL ) { // pool is empty doc_el_pool = mem_alloc( sizeof( *curr ) ); curr = doc_el_pool; for( k = 0; k < 10; k++ ) { // alloc 10 doc_els if pool empty curr->next = mem_alloc( sizeof( *curr ) ); curr = curr->next; } curr->next = NULL; } curr = doc_el_pool; doc_el_pool = curr->next; curr->next = NULL; curr->blank_lines = 0; curr->depth = 0; curr->subs_skip = 0; curr->top_skip = 0; curr->type = type; switch( type ) { case el_binc : curr->element.binc.cur_left = 0; curr->element.binc.depth = 0; curr->element.binc.y_address = 0; curr->element.binc.at_top = false; curr->element.binc.has_rec_type = false; curr->element.binc.file[0] = '\0'; break; case el_dbox : curr->element.dbox.h_start = 0; curr->element.dbox.v_start = 0; curr->element.dbox.h_len = 0; curr->element.dbox.v_len = 0; break; case el_graph : curr->element.graph.cur_left = 0; curr->element.graph.depth = 0; curr->element.graph.scale = 0; curr->element.graph.width = 0; curr->element.graph.y_address = 0; curr->element.graph.xoff = 0; curr->element.graph.yoff = 0; curr->element.graph.at_top = false; curr->element.graph.file[0] = '\0'; break; case el_hline : curr->element.hline.h_start = 0; curr->element.hline.v_start = 0; curr->element.hline.h_len = 0; break; case el_text : curr->element.text.spacing = 0; curr->element.text.first = NULL; curr->element.text.overprint = false; curr->element.text.force_op = false; break; case el_vline : curr->element.vline.h_start = 0; curr->element.vline.v_start = 0; curr->element.vline.v_len = 0; curr->element.vline.twice = true; break; default : internal_err( __FILE__, __LINE__ ); } return( curr ); }
void start_doc_sect( void ) { bool first_section; bool header; bool page_r; char * h_text; doc_section ds; hdsrc hds_lvl; int k; page_ej page_e; uint32_t page_c; uint32_t page_s; if( ProcFlags.start_section ) { return; // once is enough } if( !ProcFlags.fb_document_done ) { // the very first section/page do_layout_end_processing(); } scr_process_break(); // commit any prior text first_section = (ProcFlags.doc_sect == doc_sect_none); ProcFlags.start_section = true; ProcFlags.keep_left_margin = false; page_c = layout_work.defaults.columns; ds = ProcFlags.doc_sect_nxt; // new section if( ds == doc_sect_none ) { ds = doc_sect_body; // if text without section start assume body } /***********************************************************************/ /* process special section attributes */ /***********************************************************************/ switch( ds ) { case doc_sect_titlep : page_c = layout_work.titlep.columns; page_e = ej_yes; page_r = false; // no page number reset header = false; // no header string (ABSTRACT, ... ) output init_nest_cb(); nest_cb->p_stack = copy_to_nest_stack(); nest_cb->c_tag = t_TITLEP; nest_cb->p_stack->lineno = titlep_lineno; // correct line number break; case doc_sect_abstract : page_c = layout_work.abstract.columns; page_e = layout_work.abstract.page_eject; page_r = layout_work.abstract.page_reset; page_s = layout_work.hx.hx_sect[hds_abstract].spacing; header = layout_work.hx.hx_sect[hds_abstract].header; if( header ) { h_text = &layout_work.abstract.string; hds_lvl = hds_abstract; } break; case doc_sect_preface : page_c = layout_work.preface.columns; page_e = layout_work.preface.page_eject; page_r = layout_work.preface.page_reset; page_s = layout_work.hx.hx_sect[hds_preface].spacing; header = layout_work.hx.hx_sect[hds_preface].header; if( header ) { h_text = &layout_work.preface.string; hds_lvl = hds_preface; } break; case doc_sect_body : page_c = layout_work.body.columns; page_e = layout_work.body.page_eject; page_r = layout_work.body.page_reset; page_s = layout_work.hx.hx_sect[hds_body].spacing; header = layout_work.hx.hx_sect[hds_body].header; if( header ) { h_text = &layout_work.body.string; hds_lvl = hds_body; } break; case doc_sect_appendix : page_c = layout_work.appendix.columns; page_e = layout_work.appendix.section_eject; page_r = layout_work.appendix.page_reset; page_s = layout_work.hx.hx_sect[hds_appendix].spacing; header = false; // no section header string output, as such if( page_e != ej_no ) { page_e = ej_yes; // "even" and "odd" act like "yes" } for( k = 1; k < hds_appendix; k++ ) { // reset heading levels hd_nums[k].headn = 0; if( hd_nums[k].headnsub != NULL ) { *(hd_nums[k].headnsub->value) = '\0'; } } break; case doc_sect_backm : page_c = layout_work.backm.columns; page_e = layout_work.backm.page_eject; page_r = layout_work.backm.page_reset; page_s = layout_work.hx.hx_sect[hds_backm].spacing; header = layout_work.hx.hx_sect[hds_backm].header; if( header ) { h_text = &layout_work.backm.string; hds_lvl = hds_backm; } break; case doc_sect_index : page_c = layout_work.index.columns; page_e = layout_work.index.page_eject; page_r = layout_work.index.page_reset; page_s = layout_work.hx.hx_sect[hds_index].spacing; header = layout_work.hx.hx_sect[hds_index].header; if( header ) { h_text = &layout_work.index.index_string; hds_lvl = hds_index; } break; case doc_sect_gdoc : case doc_sect_etitlep : case doc_sect_frontm : page_c = layout_work.defaults.columns; page_e = ej_no; // no page eject page_r = false; // no page number reset page_s = layout_work.defaults.spacing; // default spacing header = false; // no section header break; case doc_sect_egdoc : page_c = layout_work.defaults.columns; page_e = ej_yes; page_r = false; // no page number reset page_s = layout_work.defaults.spacing; // default spacing header = false; // no section header break; default: internal_err( __FILE__, __LINE__ ); break; } if( first_section ) { // nothing precedes the first section if( page_e == ej_even ) { do_page_out(); // apage of first page is odd page = 0; // restart page for first text page ProcFlags.page_ejected = true; } set_section_banners( ds ); reset_t_page(); document_new_position(); // first text page ready for content } else if( page_e == ej_no ) { full_page_out(); // ensure are on last page ProcFlags.page_ejected = false; set_section_banners( ds ); reset_bot_ban(); } else { last_page_out(); // ensure last page output ProcFlags.page_ejected = true; // only first section has nothing to output if( page_e == ej_odd ) { if( (page & 1) ) { // first page will be odd do_page_out(); // emit blank page } } else if( page_e == ej_even ) { if( !(page & 1) ) { // first page will be even do_page_out(); // emit blank page } } else if( page_e != ej_yes ) { internal_err( __FILE__, __LINE__ ); } g_skip = 0; // ignore remaining skip value set_section_banners( ds ); reset_t_page(); } ProcFlags.doc_sect = ds; t_page.col_count = page_c; set_cols(); if( page_r ) { page = 0; } spacing = page_s; g_cur_left = g_page_left_org; if( header ) { line_position = pos_center; concat_save = ProcFlags.concat; ProcFlags.concat = true; justify_save = ProcFlags.justify; ProcFlags.justify = ju_off; gen_heading( h_text, NULL, 0, hds_lvl ); g_indent = 0; // reset for section body ProcFlags.concat = concat_save; ProcFlags.justify = justify_save; } g_curr_font = layout_work.defaults.font; g_cur_h_start = g_page_left_org + g_indent; ProcFlags.doc_sect = ds; }