static void gml_li_ul( const gmltag * entry ) { char * p; char bullet[3]; entry = entry; scan_err = false; p = scan_start; if( nest_cb == NULL ) { xx_nest_err( err_li_lp_no_list ); // tag must be in a list scan_start = scan_stop + 1; return; } if( ((ul_lay_tag *)(nest_cb->lay_tag))->bullet_translate ) { bullet[0] = cop_in_trans( ((ul_lay_tag *)(nest_cb->lay_tag))->bullet, ((ul_lay_tag *)(nest_cb->lay_tag))->bullet_font ); } else { bullet[0] = ((ul_lay_tag *)(nest_cb->lay_tag))->bullet; } bullet[1] = ' '; // 1 trailing space as wgml4 does bullet[2] = 0; scr_process_break(); if( ProcFlags.need_li_lp ) { // first :li for this list set_skip_vars( &((ul_lay_tag *)(nest_cb->lay_tag))->pre_skip, NULL, NULL, 1, g_curr_font ); } else if( !nest_cb->compact ) { set_skip_vars( &((ul_lay_tag *)(nest_cb->lay_tag))->skip, NULL, NULL, 1, g_curr_font ); } else { // compact set_skip_vars( NULL, NULL, NULL, 1, g_curr_font ); } spacing = ((ul_lay_tag *)(nest_cb->lay_tag))->spacing; g_curr_font = ((ul_lay_tag *)(nest_cb->lay_tag))->bullet_font; post_space = 0; g_cur_left = nest_cb->lm + nest_cb->left_indent; g_cur_h_start = g_cur_left; g_page_right = nest_cb->rm - nest_cb->right_indent; ProcFlags.keep_left_margin = true; // keep special Note indent start_line_with_string( bullet, g_curr_font, true ); g_cur_h_start = g_cur_left + conv_hor_unit( &(((ul_lay_tag *)(nest_cb->lay_tag))->align) ); if( t_line != NULL ) { if( t_line->last != NULL ) { g_cur_left += t_line->last->width + post_space; } } post_space = 0; if( g_cur_h_start > g_cur_left ) { g_cur_left = g_cur_h_start; } g_cur_h_start = g_cur_left; ju_x_start = g_cur_h_start; spacing = ((ul_lay_tag *)(nest_cb->lay_tag))->spacing; g_curr_font = ((ul_lay_tag *)(nest_cb->lay_tag))->font; if( *p == '.' ) p++; // over '.' while( *p == ' ' ) p++; // skip initial spaces ProcFlags.need_li_lp = false; if( *p ) { process_text( p, g_curr_font ); // if text fullows } scan_start = scan_stop + 1; return; }
static void gml_li_ol( const gmltag * entry ) { char * p; char * pn; uint32_t num_len; char charnumber[MAX_L_AS_STR]; entry = entry; scan_err = false; p = scan_start; if( nest_cb == NULL ) { xx_nest_err( err_li_lp_no_list ); // tag must be in a list scan_start = scan_stop + 1; return; } nest_cb->li_number++; pn = format_num( nest_cb->li_number, charnumber, MAX_L_AS_STR, ((ol_lay_tag *)(nest_cb->lay_tag))->number_style ); if( pn != NULL ) { num_len = strlen( pn ); *(pn + num_len) = ' '; // trailing space like wgml4 does *(pn + num_len + 1) = '\0'; num_len++; } else { pn = charnumber; *pn = '?'; *(pn + 1) = 0; num_len = 1; } scr_process_break(); g_curr_font = ((ol_lay_tag *)(nest_cb->lay_tag))->number_font; if( ProcFlags.need_li_lp ) { // first :li for this list set_skip_vars( &((ol_lay_tag *)(nest_cb->lay_tag))->pre_skip, NULL, NULL, 1, g_curr_font ); } else if( !nest_cb->compact ) { set_skip_vars( &((ol_lay_tag *)(nest_cb->lay_tag))->skip, NULL, NULL, 1, g_curr_font ); } else { // compact set_skip_vars( NULL, NULL, NULL, 1, g_curr_font ); } post_space = 0; g_cur_left = nest_cb->lm + nest_cb->left_indent; g_cur_h_start = g_cur_left; g_page_right = nest_cb->rm - nest_cb->right_indent; ProcFlags.keep_left_margin = true; // keep special Note indent start_line_with_string( charnumber, g_curr_font, true ); g_cur_h_start = g_cur_left + conv_hor_unit( &(((ol_lay_tag *)(nest_cb->lay_tag))->align) ); if( t_line != NULL ) { if( t_line->last != NULL ) { g_cur_left += t_line->last->width + post_space; } } post_space = 0; if( g_cur_h_start > g_cur_left ) { g_cur_left = g_cur_h_start; } g_cur_h_start = g_cur_left; ju_x_start = g_cur_h_start; spacing = ((ol_lay_tag *)(nest_cb->lay_tag))->spacing; g_curr_font = ((ol_lay_tag *)(nest_cb->lay_tag))->font; if( *p == '.' ) p++; // over '.' while( *p == ' ' ) p++; // skip initial spaces ProcFlags.need_li_lp = false; // 1. item in list processed if( *p ) { process_text( p, g_curr_font ); // if text follows } scan_start = scan_stop + 1; return; }
void gml_graphic( gml_tag gtag ) { bool depth_found = false; bool file_found = false; char file[FILENAME_MAX]; char rt_buff[MAX_FILE_ATTR]; char * p; char * pa; doc_element * cur_el; su cur_su; uint32_t depth; uint32_t scale = 100; // the initial value of width is only correct for one-column pages. uint32_t width = g_net_page_width; int32_t xoff = 0; int32_t yoff = 0; size_t len; if( (ProcFlags.doc_sect < doc_sect_gdoc) ) { if( (ProcFlags.doc_sect_nxt < doc_sect_gdoc) ) { xx_tag_err( err_tag_before_gdoc, gml_tagname( gtag ) ); scan_start = scan_stop; return; } } len = 0; file[0] = '\0'; rt_buff[0] = '\0'; p = scan_start; for( ;; ) { while( *p == ' ' ) { // over WS to attribute p++; } if( *p == '\0' ) { // end of line: get new line if( !(input_cbs->fmflags & II_eof) ) { if( get_line( true ) ) { // next line for missing attribute process_line(); if( (*scan_start == SCR_char) || // cw found: end-of-tag (*scan_start == GML_char) ) { // tag found: end-of-tag ProcFlags.tag_end_found = true; break; } else { p = scan_start; // new line is part of current tag continue; } } } } if( !strnicmp( "file", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } file_found = true; len = val_len; if( len >= FILENAME_MAX ) len = FILENAME_MAX - 1; memcpy( file, val_start, len ); file[len] = '\0'; split_attr_file( file, rt_buff, sizeof( rt_buff ) ); if( (rt_buff[0] != '\0') ) { xx_warn( wng_rec_type_graphic ); } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "depth", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } depth_found = true; pa = val_start; if( att_val_to_su( &cur_su, true ) ) { return; } depth = conv_vert_unit( &cur_su, g_spacing_ln ); if( depth == 0 ) { xx_line_err( err_inv_depth_graphic, pa ); scan_start = scan_stop; return; } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "width", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } if( !strnicmp( "page", val_start, 4 ) ) { // default value is the correct value to use } else if( !strnicmp( "column", val_start, 6 ) ) { // default value is the correct value to use } else { // value actually specifies the width pa = val_start; if( att_val_to_su( &cur_su, true ) ) { return; } width = conv_hor_unit( &cur_su ); if( width == 0 ) { xx_line_err( err_inv_width_graphic, pa ); scan_start = scan_stop; return; } /* there should be a check somewhere for width > page width */ } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "scale", p, 5 ) ) { p += 5; p = get_att_value( p ); if( val_start == NULL ) { break; } pa = val_start; if( (*pa == '+') || (*pa == '-') ) { // signs not allowed xx_line_err( err_num_too_large, pa ); scan_start = scan_stop; return; } scale = 0; while( (*pa >= '0') && (*pa <= '9') ) { // convert to number scale = (10 * scale) + (*pa - '0'); pa++; if( (pa - val_start) > val_len ) { // value end reached break; } } if( scale > 0x7fffffff ) { // wgml 4.0 limit xx_line_err( err_num_too_large, val_start ); scan_start = scan_stop; return; } if( (pa - val_start) < val_len ) { // value continues on xx_line_err( err_num_too_large, val_start ); scan_start = scan_stop; return; } if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "xoff", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } if( att_val_to_su( &cur_su, false ) ) { return; } xoff = conv_hor_unit( &cur_su ); if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "yoff", p, 4 ) ) { p += 4; p = get_att_value( p ); if( val_start == NULL ) { break; } if( att_val_to_su( &cur_su, false ) ) { return; } yoff = conv_vert_unit( &cur_su, g_spacing_ln ); if( ProcFlags.tag_end_found ) { break; } } else { // no match = end-of-tag in wgml 4.0 ProcFlags.tag_end_found = true; break; } } if( !depth_found || !file_found ) { // detect missing required attributes xx_err( err_att_missing ); scan_start = scan_stop; return; } scr_process_break(); // flush existing text start_doc_sect(); // if not already done cur_el = alloc_doc_el( el_graph ); cur_el->depth = depth; // always used with GRAPHIC if( !ProcFlags.ps_device ) { // character devices ignore SK & post_skip g_skip = 0; g_post_skip = 0; } set_skip_vars( NULL, NULL, NULL, 1, g_curr_font ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->subs_skip = g_subs_skip; g_subs_skip = 0; cur_el->top_skip = g_top_skip; g_top_skip = 0; cur_el->element.graph.cur_left = g_cur_h_start; cur_el->element.graph.depth = depth; cur_el->element.graph.scale = scale; cur_el->element.graph.width = width; cur_el->element.graph.xoff = xoff; cur_el->element.graph.yoff = yoff; ProcFlags.skips_valid = false; memcpy( cur_el->element.graph.file, file, len + 1 ); insert_col_main( cur_el ); if( *p == '.' ) { p++; } scan_start = p; // process following text }
static void gen_toc( void ) { bool levels[7]; // track levels char buffer[11]; char postfix[12]; ffh_entry * curr; int i; int j; uint32_t cur_level; uint32_t indent[7]; uint32_t size; if( hd_list == NULL ) return; // no hd_list, no TOC /* Insert TOC into current section */ last_page_out(); // ensure are on new page g_skip = 0; // ignore remaining skip value set_section_banners( doc_sect_toc ); reset_t_page(); /* Set TOC margins and other values */ g_page_left = g_page_left_org + 2 * conv_hor_unit( &layout_work.toc.left_adjust, g_curr_font ); // matches wgml 4.0 g_page_right = g_page_right_org - conv_hor_unit( &layout_work.toc.right_adjust, g_curr_font ); size = conv_hor_unit( &layout_work.tocpgnum.size, g_curr_font ); // space from fill to right edge figlist_toc_tabs( layout_work.toc.fill_string, size ); /* Initialize levels and indent values */ for( i = 0; i < 7; i++ ) { levels[i] = false; indent[i] = 0; } /* Get converted indent values, which are cumulative */ for( i = 0; i < 7; i++ ) { for( j = i; j < 7; j++ ) { indent[j] += conv_hor_unit( &layout_work.tochx[i].indent, g_curr_font ); } } /* Output TOC */ concat_save = ProcFlags.concat; ProcFlags.concat = true; justify_save = ProcFlags.justify; ProcFlags.justify = ju_off; ProcFlags.keep_left_margin = true; // keep all indents while outputting text curr = hd_list; while( curr != NULL ) { cur_level = curr->number; for( i = 0; i < 7; i++ ) { if( i > cur_level ) { // all lower levels are inactive levels[i] = false; } } if( cur_level < layout_work.toc.toc_levels ) { g_curr_font = layout_work.tochx[cur_level].font; if( levels[cur_level] ) { spacing = layout_work.toc.spacing; set_skip_vars( &layout_work.tochx[cur_level].skip, NULL, NULL, spacing, g_curr_font ); } else { spacing = 1; set_skip_vars( &layout_work.tochx[cur_level].pre_skip, NULL, &layout_work.tochx[cur_level].post_skip, spacing, g_curr_font ); } g_cur_left = g_page_left + indent[cur_level]; g_cur_h_start = g_cur_left; if( curr->prefix != NULL ) { process_text( curr->prefix, g_curr_font ); g_cur_left = t_line->last->x_address + t_line->last->width + wgml_fonts[g_curr_font].spc_width; g_cur_h_start = g_cur_left; ProcFlags.ct = true; // emulate CT post_space = 0; } else { t_line = alloc_text_line(); // capture spacing if no prefix } if( !levels[cur_level] ) { spacing = layout_work.toc.spacing; set_skip_vars( NULL, NULL, NULL, spacing, g_curr_font ); } if( curr->text != NULL ) { g_page_right -= size; if( ProcFlags.has_aa_block ) { // matches wgml 4.0 g_page_right -= tab_col; } else { g_page_right -= 3 * tab_col; } ProcFlags.stop_xspc = true; // suppress 2nd space after stop process_text( curr->text, g_curr_font ); if( ProcFlags.has_aa_block ) { // matches wgml 4.0 g_page_right += tab_col; } else { g_page_right += 3 * tab_col; } g_page_right += size; } ProcFlags.ct = true; // emulate CT g_curr_font = FONT0; process_text( "$", g_curr_font ); format_num( curr->pageno, &buffer, sizeof( buffer ), curr->style ); strcpy_s( postfix, 12, "$" ); // insert tab characters strcat_s( postfix, 12, buffer ); // append page number g_curr_font = layout_work.tocpgnum.font; process_text( postfix, g_curr_font ); } scr_process_break(); // ensure line break levels[cur_level] = true; // first entry of level done curr = curr->next; } ProcFlags.concat = concat_save; ProcFlags.justify = justify_save; /* Re-establish current section */ last_page_out(); // ensure all pages output set_section_banners( ProcFlags.doc_sect ); reset_t_page(); return; }
static void gen_figlist( void ) { char buffer[11]; char postfix[12]; ffh_entry * curr; uint32_t size; if( fig_list == NULL ) return; // no fig_list, no FIGLIST /* Insert FIGLIST into current section */ last_page_out(); // ensure are on new page g_skip = 0; // ignore remaining skip value set_section_banners( doc_sect_figlist ); reset_t_page(); /* Set FIGLIST margins and other values */ g_page_left = g_page_left_org + 2 * conv_hor_unit( &layout_work.figlist.left_adjust, g_curr_font ); // matches wgml 4.0 g_page_right = g_page_right_org - conv_hor_unit( &layout_work.figlist.right_adjust, g_curr_font ); size = conv_hor_unit( &layout_work.flpgnum.size, g_curr_font ); // space from fill to right edge figlist_toc_tabs( layout_work.figlist.fill_string, size ); /* Output FIGLIST */ concat_save = ProcFlags.concat; ProcFlags.concat = true; justify_save = ProcFlags.justify; ProcFlags.justify = ju_off; ProcFlags.keep_left_margin = true; // keep all indents while outputting text curr = fig_list; while( curr != NULL ) { if( curr->flags & ffh_figcap ) { // no FIGCAP used, no FIGLIST output g_curr_font = FONT0; // wgml 4.0 uses font 0 if( ProcFlags.page_started ) { // not on first entry spacing = layout_work.figlist.spacing; set_skip_vars( NULL, NULL, NULL, spacing, g_curr_font ); } g_cur_left = g_page_left; g_cur_h_start = g_cur_left; process_text( curr->prefix, g_curr_font ); // caption prefix if( curr->text != NULL ) { g_cur_left = t_line->last->x_address + t_line->last->width + wgml_fonts[g_curr_font].spc_width; g_cur_h_start = g_cur_left; ProcFlags.ct = true; // emulate CT ProcFlags.stop_xspc = true; // suppress 2nd space after stops post_space = 0; g_page_right -= size; if( ProcFlags.has_aa_block ) { // matches wgml 4.0 g_page_right -= tab_col; } else { g_page_right -= 3 * tab_col; } if( !ProcFlags.page_started ) { // first entry wrapping spacing = layout_work.figlist.spacing; } set_skip_vars( &layout_work.figlist.skip, NULL, NULL, spacing, g_curr_font ); process_text( curr->text, g_curr_font );// caption text if( ProcFlags.has_aa_block ) { // matches wgml 4.0 g_page_right += tab_col; } else { g_page_right += 3 * tab_col; } g_page_right += size; } ProcFlags.ct = true; // emulate CT g_curr_font = FONT0; process_text( "$", g_curr_font ); format_num( curr->pageno, &buffer, sizeof( buffer ), curr->style ); strcpy_s( postfix, 12, "$" ); // insert tab characters strcat_s( postfix, 12, buffer ); // append page number g_curr_font = layout_work.flpgnum.font; process_text( postfix, g_curr_font ); } scr_process_break(); // ensure line break curr = curr->next; } ProcFlags.concat = concat_save; ProcFlags.justify = justify_save; /* Re-establish current section */ last_page_out(); // ensure all pages output set_section_banners( ProcFlags.doc_sect ); reset_t_page(); return; }
static int32_t round_indent( su * work ) { return( conv_hor_unit( work ) * CPI / g_resh * g_resh / CPI ); }