void start_line_with_string( const char *text, font_number font, bool leave_1space ) { text_chars *n_char; // new text char size_t count; unsigned space_count; count = strlen( text ); if( count == 0 ) { return; } space_count = 0; while( *(text + count - 1) == ' ' ) { // strip trailing spaces space_count++; if( --count == 0 ) { break; } } if( leave_1space && space_count > 0 ) {// for ordered :LI keep 1 trailing space space_count--; count++; } n_char = alloc_text_chars( text, count, font ); n_char->x_address = g_cur_h_start; ju_x_start = g_cur_h_start; input_cbs->fmflags &= ~II_sol; // no longer start of line n_char->width = cop_text_width( n_char->text, n_char->count, font ); /***********************************************************/ /* Test if word hits right margin */ /***********************************************************/ if( n_char->x_address + n_char->width > g_page_right ) { process_line_full( t_line, ProcFlags.concat ); t_line = alloc_text_line(); n_char->x_address = g_cur_h_start; } if( t_line == NULL ) { t_line = alloc_text_line(); } if( t_line->first == NULL ) { // first element in output line t_line->first = n_char; t_line->line_height = wgml_fonts[font].line_height; ju_x_start = n_char->x_address; ProcFlags.line_started = true; } else { t_line->last->next = n_char; n_char->prev = t_line->last; } t_line->last = n_char; g_cur_h_start = n_char->x_address + n_char->width; post_space = space_count * wgml_fonts[layout_work.defaults.font].spc_width; }
static void doc_header( su *p_sk, su *top_sk, xx_str *h_string, font_number font, spacing_line spacing_ln, bool no_eject ) { doc_element * cur_el; font_number font_save; int32_t h_left; text_chars * curr_t; text_line * hd_line; font_save = g_curr_font; g_curr_font = font; g_curr_font = font_save; set_skip_vars( NULL, top_sk, p_sk, spacing_ln, g_curr_font ); if( (h_string == NULL) || (*h_string == '\0') || (*h_string == ' ') || (*h_string == '\t') ) { /********************************************************/ /* header contained "yes" but the string was empty: */ /* the OW docs do this with APPENDIX for PS/PDF output */ /********************************************************/ hd_line = alloc_text_line(); // defaults work } else { curr_t = alloc_text_chars( h_string, strlen( h_string ), font ); curr_t->width = cop_text_width( curr_t->text, curr_t->count, font ); h_left = g_page_left +(g_page_right - g_page_left - curr_t->width) / 2; curr_t->x_address = h_left; hd_line = alloc_text_line(); hd_line->first = curr_t; hd_line->line_height = wgml_fonts[font].line_height; } if( input_cbs->fmflags & II_research ) { test_out_t_line( hd_line ); } cur_el = alloc_doc_el( el_text ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->depth = hd_line->line_height; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = hd_line; ProcFlags.skips_valid = false; hd_line = NULL; if( no_eject ) { insert_col_main( cur_el ); } else { insert_page_width( cur_el ); } }
void gml_title( const gmltag * entry ) { char * p; doc_element * cur_el; text_line * p_line = NULL; int8_t t_spacing; font_number font_save; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, entry->tagname, ":TITLEP section" ); err_count++; show_include_stack(); } p = scan_start; if( *p && *p != '.' ) p++; while( *p == ' ' ) { // over WS to attribute p++; } if( *p && ! (strnicmp( "stitle ", p, 7 ) && // look for stitle strnicmp( "stitle=", p, 7 )) ) { char quote; char * valstart; p += 6; while( *p == ' ' ) { p++; } if( *p == '=' ) { p++; while( *p == ' ' ) { p++; } } if( *p == '"' || *p == '\'' ) { quote = *p; ++p; } else { quote = ' '; } valstart = p; while( *p && *p != quote ) { ++p; } *p = '\0'; if( !ProcFlags.stitle_seen ) { // first stitle goes into dictionary add_symvar( &global_dict, "$stitle", valstart, no_subscript, 0 ); ProcFlags.stitle_seen = true; } p++; } if( *p == '.' ) p++; // over '.' if( !ProcFlags.title_text_seen ) { if( *p ) { // first title goes into dictionary add_symvar( &global_dict, "$title", p, no_subscript, 0 ); } } start_doc_sect(); // if not already done font_save = g_curr_font; g_curr_font = layout_work.title.font; t_spacing = layout_work.titlep.spacing; if( !ProcFlags.title_tag_top ) { set_skip_vars( NULL, &layout_work.title.pre_top_skip, NULL, t_spacing, g_curr_font ); ProcFlags.title_tag_top = true; } else { set_skip_vars( &layout_work.title.skip, NULL, NULL, t_spacing, g_curr_font ); } p_line = alloc_text_line(); p_line->line_height = wgml_fonts[g_curr_font].line_height; if( *p ) { prep_title_line( p_line, p ); } cur_el = init_doc_el( el_text, p_line->line_height ); cur_el->element.text.first = p_line; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop + 1; }
void gml_date( gml_tag gtag ) { char * p; doc_element * cur_el; text_line * p_line; spacing_line spacing_ln; font_number font_save; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, gml_tagname( gtag ), ":TITLEP section" ); err_count++; show_include_stack(); } if( ProcFlags.date_tag_seen ) { // only one DATE tag allowed xx_line_err( err_2nd_date, buff2 ); } ProcFlags.date_tag_seen = true; p = scan_start; if( *p && *p == '.' ) p++; // over . to docnum while( *p == ' ' ) { // over WS to attribute p++; } if( *p ) { // date specified add_symvar( &global_dict, "date", p, no_subscript, 0 ); } start_doc_sect(); // if not already done p_line = alloc_text_line(); p_line->line_height = wgml_fonts[layout_work.docnum.font].line_height; prep_date_line( p_line, p ); spacing_ln = layout_work.titlep.spacing; font_save = g_curr_font; g_curr_font = layout_work.date.font; /************************************************************/ /* pre_skip is treated as pre_top_skip because it is */ /* always used at the top of the page, despite the docs */ /************************************************************/ set_skip_vars( NULL, &layout_work.date.pre_skip, NULL, spacing_ln, g_curr_font ); cur_el = alloc_doc_el( el_text ); cur_el->depth = p_line->line_height + g_spacing; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = p_line; ProcFlags.skips_valid = false; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop; }
static void out_ban_common( banner_lay_tag * ban, bool top ) { ban_column * last; text_chars * curr_t; text_chars * curr_p; uint32_t ban_left; uint32_t h_left; uint32_t ban_right; uint32_t h_right; uint32_t reg_indent; uint32_t curr_x; int k; reg_text[0] = NULL; reg_text[1] = NULL; reg_text[2] = NULL; ban_line.first = NULL; /* calc banner horizontal margins */ ban_left = g_page_left_org + ban->ban_left_adjust; ban_right = g_page_right_org - ban->ban_right_adjust; content_reg( ban ); curr_x = 0; for( k = 0; k < 3; ++k ) { // for all region parts if( reg_text[k] == NULL ) { continue; // skip empty part } if( top ) { g_prev_font = reg_text[k]->font; } if( ban_line.first == NULL ) { ban_line.first = reg_text[k]; ban_line.line_height = wgml_fonts[reg_text[k]->font].line_height; } else { ban_line.last->next = reg_text[k]; reg_text[k]->prev = ban_line.last; } if( ban_line.line_height < wgml_fonts[reg_text[k]->font].line_height ) { ban_line.line_height = wgml_fonts[reg_text[k]->font].line_height; } curr_t = reg_text[k]; ban_line.last = reg_text[k]; h_left = ban_left; h_right = ban_right; reg_indent = ban->region->reg_indent; if( ban->region->hoffset.su_u >= SU_lay_left ) { // symbolic if( ban->region->hoffset.su_u == SU_lay_left ) { h_left += reg_indent; } else if( ban->region->hoffset.su_u == SU_lay_right ) { h_right -= reg_indent; } else if( ban->region->hoffset.su_u == SU_lay_centre ) { h_left += reg_indent; } } else { // in horiz space units h_left += reg_indent + ban->region->reg_hoffset; } if( ban->region->region_position == pos_center || k == 1) { if( h_left + curr_t->width < h_right ) { h_left += (h_right - h_left - curr_t->width) / 2; curr_x = h_left; } } else if( ban->region->region_position == pos_right || k == 2) { h_left = h_right - curr_t->width; curr_x = h_left; } if( curr_x == 0 ) { curr_x = h_left; } curr_t->x_address = curr_x; curr_x += curr_t->width; } if( ban_line.first != NULL) { if( input_cbs->fmflags & II_research ) { test_out_t_line( &ban_line ); } /*******************************************************************/ /* truncate the left part(s) in case of overlap */ /*******************************************************************/ curr_p = ban_line.first; for( curr_t = curr_p->next; curr_t != NULL; curr_t = curr_t->next ) { while( (curr_p->x_address + curr_p->width) > curr_t->x_address ) { if( curr_p->count < 2) {// sanity check break; } curr_p->count -= 1; // truncate text, adjust width curr_p->width -= wgml_fonts[curr_p->font].width_table[(unsigned char)curr_p->text[curr_p->count]]; } curr_p = curr_t; } /* insert ban_line into t_page */ /* this will do multiple columns, but not in sorted order */ /* ban_line is taken to be a linked list of text_lines when */ /* a banregion has depth > 1 and enough text to fill the */ /* first line */ /* this will need adjustment as banner output is enhanced */ if( top ) { if( t_page.top_ban == NULL ) { t_page.top_ban = alloc_ban_col(); last = t_page.top_ban; } else { for( ; last->next != NULL; last = last->next ); last->next = alloc_ban_col(); last = last->next; } } else { if( t_page.bot_ban == NULL ) { t_page.bot_ban = alloc_ban_col(); last = t_page.bot_ban; } else { for( ; last->next != NULL; last = last->next ); last->next = alloc_ban_col(); last = last->next; } } last->first = alloc_doc_el( el_text ); last->first->top_skip = ban->top_line->reg_voffset; last->first->subs_skip = ban->top_line->reg_voffset; last->first->element.text.first = alloc_text_line(); last->first->element.text.first->next = ban_line.next; last->first->element.text.first->line_height = ban_line.line_height; last->first->element.text.first->spacing = 0; // hbus; banners are always single-spaced last->first->element.text.first->y_address = ban_line.y_address; last->first->element.text.first->first = ban_line.first; last->first->element.text.first->last = ban_line.last; ban_line.first = NULL; } }
void gml_docnum( const gmltag * entry ) { char * p; doc_element * cur_el; text_line * p_line; int8_t d_spacing; font_number font_save; int32_t rc; symsub * docnumval; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, entry->tagname, ":TITLEP section" ); err_count++; show_include_stack(); } if( ProcFlags.docnum_tag_seen ) { // only one DOCNUM tag allowed xx_line_err( err_2nd_docnum, buff2 ); } ProcFlags.docnum_tag_seen = true; p = scan_start; if( *p && *p == '.' ) p++; // over . to docnum while( *p == ' ' ) { // over WS to attribute p++; } rc = find_symvar( &sys_dict, "$docnum", no_subscript, &docnumval ); if( *p ) { // docnum specified strcpy_s( docnumval->value, 60, p ); } else { *(docnumval->value) = 0; } start_doc_sect(); // if not already done p_line = alloc_text_line(); p_line->line_height = wgml_fonts[layout_work.docnum.font].line_height; prep_docnum_line( p_line, docnumval->value ); d_spacing = layout_work.titlep.spacing; font_save = g_curr_font; g_curr_font = layout_work.docnum.font; /************************************************************/ /* pre_skip is treated as pre_top_skip because it is */ /* always used at the top of the page, despite the docs */ /************************************************************/ set_skip_vars( NULL, &layout_work.docnum.pre_skip, NULL, d_spacing, g_curr_font ); cur_el = alloc_doc_el( el_text ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->depth = p_line->line_height + g_spacing; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = p_line; ProcFlags.skips_valid = false; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop + 1; }
static void hx_header( int hx_lvl, const char *hnumstr, const char *txt ) { doc_element * cur_el; font_number font_save; font_number font; int32_t width; int32_t widthn; text_chars * curr_t; text_chars * curr_tn; text_line * hd_line; hd_line = NULL; font_save = g_curr_font; g_spacing_ln = layout_work.hx[hx_lvl].spacing; if( layout_work.hx[hx_lvl].line_break ) { set_skip_vars( &layout_work.hx[hx_lvl].pre_skip, &layout_work.hx[hx_lvl].pre_top_skip, &layout_work.hx[hx_lvl].post_skip, g_spacing_ln, layout_work.hx[hx_lvl].number_font ); } else { set_skip_vars( &layout_work.hx[hx_lvl].pre_skip, &layout_work.hx[hx_lvl].pre_top_skip, NULL, g_spacing_ln, layout_work.hx[hx_lvl].number_font ); } post_space = 0; curr_t = NULL; curr_tn = NULL; width = 0; widthn = 0; hd_line = alloc_text_line(); if( layout_work.hx[hx_lvl].number_form != num_none ) { font = layout_work.hx[hx_lvl].number_font; curr_tn = alloc_text_chars( hnumstr, strlen( hnumstr ), font ); curr_tn->width = cop_text_width( curr_tn->text, curr_tn->count, font ); widthn = curr_tn->width + wgml_fonts[font].spc_width;; hd_line->first = curr_tn; hd_line->line_height = wgml_fonts[font].line_height; hd_line->last = curr_tn; } if( (txt != NULL) && (*txt != '\0') ) { font = layout_work.hx[hx_lvl].font; curr_t = alloc_text_chars( txt, strlen( txt ), font ); curr_t->width = cop_text_width( curr_t->text, curr_t->count, font ); width = curr_t->width; if( hd_line->first == NULL ) { hd_line->first = curr_t; } else { curr_tn->next = curr_t; curr_t->prev = curr_tn; } hd_line->last = curr_t; if( hd_line->line_height < wgml_fonts[font].line_height ) { hd_line->line_height = wgml_fonts[font].line_height; } } if( curr_t == NULL ) { curr_t = curr_tn; curr_tn = NULL; width = widthn; widthn = 0; } g_cur_left = g_page_left + conv_hor_unit( &layout_work.hx[hx_lvl].indent ) + conv_hor_unit( &layout_work.hx[hx_lvl].align ); if( layout_work.hx[hx_lvl].page_position == pos_left ) { if( curr_tn != NULL ) { curr_tn->x_address = g_cur_left; } curr_t->x_address = g_cur_left + widthn; } else { if( layout_work.hx[hx_lvl].page_position == pos_center ) { curr_t->x_address = g_cur_left + widthn + (g_page_right - g_cur_left - widthn - width) / 2; } else { curr_t->x_address = g_page_right - width; } if( curr_tn != NULL ) { curr_tn->x_address = curr_t->x_address - widthn; } } if( input_cbs->fmflags & II_research ) { test_out_t_line( hd_line ); } cur_el = alloc_doc_el( el_text ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->depth = hd_line->line_height; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = hd_line; ProcFlags.skips_valid = false; hd_line = NULL; if( layout_work.hx[hx_lvl].page_eject == ej_no ) { insert_col_main( cur_el ); } else { insert_page_width( cur_el ); } }
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; }