static void finish_banners( void ) { banner_lay_tag * cur_ban; region_lay_tag * cur_reg; region_lay_tag * top_line_reg; font_number s_font; uint32_t ban_line; uint32_t max_reg_depth; font_number max_reg_font; uint32_t min_top_line; s_font = g_curr_font; for( cur_ban = layout_work.banner; cur_ban != NULL; cur_ban = cur_ban->next ) { ban_line = 0; max_reg_depth = 0; max_reg_font = 0; min_top_line = UINT32_MAX; // start at very large positive number top_line_reg = NULL; for( cur_reg = cur_ban->region; cur_reg != NULL; cur_reg = cur_reg->next ) { g_curr_font = s_font; // horizontal attributes use default font cur_reg->reg_indent = conv_hor_unit( &cur_reg->indent ); cur_reg->reg_hoffset = conv_hor_unit( &cur_reg->hoffset ); cur_reg->reg_width = conv_hor_unit( &cur_reg->width ); g_curr_font = cur_reg->font; // vertical attributes use the banregion font cur_reg->reg_voffset = conv_vert_unit( &cur_reg->voffset, 1 ); cur_reg->reg_depth = conv_vert_unit( &cur_reg->depth, 1 ); if( max_reg_depth < cur_reg->reg_voffset + cur_reg->reg_depth ) { max_reg_depth = cur_reg->reg_voffset + cur_reg->reg_depth; } if( ban_line < wgml_fonts[cur_reg->font].line_height ) { max_reg_font = cur_reg->font; ban_line = wgml_fonts[max_reg_font].line_height; } if( min_top_line > cur_reg->reg_voffset + cur_reg->reg_depth ) { min_top_line = cur_reg->reg_voffset + cur_reg->reg_depth; top_line_reg = cur_reg; } } g_curr_font = s_font; // horizontal attributes use default font cur_ban->ban_left_adjust = conv_hor_unit( &cur_ban->left_adjust ); cur_ban->ban_right_adjust = conv_hor_unit( &cur_ban->right_adjust ); g_curr_font = max_reg_font; // vertical attribute uses the largest banregion font cur_ban->ban_depth = conv_vert_unit( &cur_ban->depth, 1 ); cur_ban->top_line = top_line_reg; if( cur_ban->ban_depth < max_reg_depth ) { xx_err( err_banreg_too_deep ); cur_ban->ban_depth = max_reg_depth; } } g_curr_font = s_font; return; }
void set_skip_vars( su * pre_skip, su * pre_top_skip, su * post_skip, uint32_t spacing, uint8_t font ) { int32_t skiptop; int32_t skippost; int32_t skippre; int32_t skipsk; skipsk = calc_skip_value(); // pending .sk value? if( pre_skip != NULL ) { skippre = conv_vert_unit( pre_skip, spacing ); } else { skippre = 0; } if( pre_top_skip != NULL ) { skiptop = conv_vert_unit( pre_top_skip, spacing ); } else { skiptop = 0; } if( g_post_skip > skipsk ) { // merge sk-skip & post-skip per Wiki skippost = g_post_skip; } else { skippost = skipsk; } if( skippre > skiptop ) { // merge pre-skip & pre-top-skip per Wiki if( skippre > (2 * skiptop) ) { skippre -= skiptop; } else { skippre = skiptop; } } else { skippre = skiptop; } if( skippost > skippre ) { // final merger per Wiki skippre = skippost; } g_subs_skip = skippre; g_top_skip = skiptop; if( post_skip != NULL ) { g_post_skip = conv_vert_unit( post_skip, spacing ); } else { g_post_skip = 0; } g_blank_lines = blank_lines * wgml_fonts[font].line_height; blank_lines = 0; g_spacing = (spacing - 1) * wgml_fonts[font].line_height; ProcFlags.skips_valid = true; return; }
su *greater_su( su *su_a, su *su_b, spacing_line spacing_ln ) { uint32_t val_a; uint32_t val_b; val_a = conv_vert_unit( su_a, spacing_ln ); val_b = conv_vert_unit( su_b, spacing_ln ); if( val_a > val_b ) { return( su_a ); } else { return( su_b ); } }
void gml_binclude( gml_tag gtag ) { bool depth_found = false; bool file_found = false; bool has_rec_type = false; bool reposition; bool reposition_found = false; char file[FILENAME_MAX]; char rt_buff[MAX_FILE_ATTR]; char * p; doc_element * cur_el; su depth_su; uint32_t depth; 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, MAX_FILE_ATTR ); if( (rt_buff[0] != '\0') ) { has_rec_type = true; if( rt_buff[0] != 't' ) { xx_warn( wng_rec_type_binclude ); } } 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; if( att_val_to_su( &depth_su, true ) ) { return; } depth = conv_vert_unit( &depth_su, g_spacing_ln ); if( ProcFlags.tag_end_found ) { break; } } else if( !strnicmp( "reposition", p, 10 ) ) { p += 10; p = get_att_value( p ); if( val_start == NULL ) { break; } reposition_found = true; if( !strnicmp( "start", val_start, 5 ) ) { reposition = true; // moving following text down by depth } else if( !strnicmp( "end", val_start, 3 ) ) { reposition = false; // device at proper position after insertion } else { xx_line_err( err_inv_att_val, val_start ); scan_start = scan_stop; return; } if( ProcFlags.tag_end_found ) { break; } } else { // no match = end-of-tag in wgml 4.0 ProcFlags.tag_end_found = true; break; } } // detect missing required attributes if( !depth_found || !file_found || !reposition_found ) { 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_binc ); if( reposition && depth ) { cur_el->depth = depth; // otherwise, it will be "0" } if( depth > 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; cur_el->top_skip = g_top_skip; } cur_el->element.binc.depth = depth; cur_el->element.binc.cur_left = g_cur_h_start; cur_el->element.binc.has_rec_type = has_rec_type; ProcFlags.skips_valid = false; memcpy( cur_el->element.binc.file, file, len + 1 ); insert_col_main( cur_el ); scan_start = scan_stop; // skip following text }
void init_page_geometry( void ) { int k; uint32_t page_depth_org; uint32_t net_top_margin; uint32_t net_y_start; uint32_t rm_test; uint32_t top_margin; uint32_t y_start_correction; #if 0 // activate for multi column TBD uint32_t offset; #endif g_resh = bin_device->horizontal_base_units; // hor resolution &sysresh g_resv = bin_device->vertical_base_units; // vert resolution &sysresv spacing = layout_work.defaults.spacing; g_cur_threshold = layout_work.widow.threshold; g_max_char_width = 0; g_max_line_height = 0; for( k = 0; k < wgml_font_cnt; k++ ) { if( g_max_char_width < wgml_fonts[k].default_width ) g_max_char_width = wgml_fonts[k].default_width; if( g_max_line_height < wgml_fonts[k].line_height ) g_max_line_height = wgml_fonts[k].line_height; } g_curr_font = layout_work.defaults.font; lm = conv_hor_unit( &layout_work.page.left_margin ) - bin_device->x_offset; // left margin &syspagelm if( lm < 0 ) { // wgml 4.0 limits value lm = 0; } rm = conv_hor_unit( &layout_work.page.right_margin ) - bin_device->x_offset; // right margin &syspagerm rm_test = bin_device->horizontal_base_units / 4; if( (bin_device->horizontal_base_units % 4) > 0 ) { rm_test++; // round up if any remainder } if( rm < rm_test ) { // wgml 4.0 limits value xx_err( err_right_margin_2_small ); // candidate Severe Error g_suicide(); // no recovery possible } g_page_left_org = lm + bin_device->x_start; if( g_page_left_org < bin_device->x_start ) g_page_left_org = bin_device->x_start; g_page_left = g_page_left_org; g_cur_left = g_page_left; // set initial value g_page_right_org = rm + bin_device->x_start; if( g_page_right_org > bin_device->page_width ) g_page_right_org = bin_device->page_width; g_page_right = g_page_right_org; if( g_page_right > bin_device->page_width ) {// output must appear on page xx_err( err_margins_inverted ); // candidate Severe Error g_suicide(); // no recovery possible } if( g_page_left >= g_page_right ) { // margins cannot be inverted xx_err( err_margins_inverted ); // candidate Severe Error g_suicide(); // no recovery possible } g_net_page_width = rm - lm; g_ll = g_net_page_width * CPI / bin_device->horizontal_base_units; // &sysll top_margin = conv_vert_unit( &layout_work.page.top_margin, 1 ); page_depth_org = conv_vert_unit( &layout_work.page.depth, 1 ); if( bin_device->y_offset > page_depth_org ) { xx_err( err_page_depth_too_small ); // candidate Severe Error g_suicide(); // no recovery possible } else { g_page_depth = page_depth_org - bin_device->y_offset; // &syspaged } if( bin_device->y_offset < top_margin ) { net_top_margin = top_margin - bin_device->y_offset; } else { net_top_margin = 0; } if( bin_driver->y_positive == 0 ) { g_page_top = bin_device->y_start - net_top_margin; if( g_page_depth > bin_device->y_start ) { /* see Wiki for discussion, wgml 4.0 differs here */ xx_err( err_page_depth_too_big ); // candidate Severe Error g_suicide(); // no recovery possible } else { g_page_bottom = bin_device->y_start - g_page_depth;// end of text area } g_net_page_depth = g_page_top - g_page_bottom; lcmax = 1 + (g_net_page_depth + bin_device->y_offset) / wgml_fonts[g_curr_font].line_height; // usable no of lines } else { net_y_start = bin_device->y_start; if( net_y_start < net_top_margin ) net_y_start = net_top_margin; if( bin_device->y_start > net_top_margin ) { y_start_correction = bin_device->y_start - net_top_margin; if( y_start_correction > wgml_fonts[g_curr_font].line_height ) { y_start_correction = wgml_fonts[g_curr_font].line_height; } } else { y_start_correction = 0; } g_page_top = net_y_start - y_start_correction; g_page_bottom = g_page_top + g_page_depth; g_net_page_depth = g_page_bottom - g_page_top; lcmax = g_net_page_depth; } g_page_bottom_org = g_page_bottom;// save for possible bot banner calculation g_page_top_org = g_page_top;// save top for possible bot banner calculation g_cd = layout_work.defaults.columns;// no of columns &syscd g_gutter = conv_hor_unit( &layout_work.defaults.gutter ); // &sysgutter #if 0 // activate for multi column TBD if( g_cd > 1 ) { // multi column layout if( g_cd > 9 ) { // no more than 9 columns g_cd = 9; // this limit is found in script_tso.txt // for .cd control word } g_cl = (g_net_page_width - (g_cd - 1) * g_gutter ) / (g_cd - 1); // column length offset = g_page_left; for( k = 0; k < g_cd; ++k ) { g_offset[k] = offset; // start of each column offset += g_cl + g_gutter; } for( ; k < 9; ++k ) { g_offset[k] = 0; // dummy start of undefined columns } } else { g_cl = g_ll; } #else g_cl = g_ll; // column length &syscl // This is what wgml 4 does, even if in multi column mode TBD #endif // if( GlobalFlags.firstpass && GlobalFlags.research ) { // show values TBD if( GlobalFlags.firstpass ) { out_msg( "\ntm:%d lm:%d rm:%d top margin:%d depth:%d\n\n", tm, lm, rm, top_margin, g_page_depth ); out_msg( "dev:%s page_w:%d page_d:%d hor_u:%d ver_u:%d x_s:%d y_s:%d" " x_o:%d y_o:%d\n\n", bin_device->driver_name, bin_device->page_width, bin_device->page_depth, bin_device->horizontal_base_units, bin_device->vertical_base_units, bin_device->x_start, bin_device->y_start, bin_device->x_offset, bin_device->y_offset ); out_msg( "default font number:%d font_count:%d\n", g_curr_font, wgml_font_cnt ); for( k = 0; k < wgml_font_cnt; ++k ) { out_msg( "font:%d def_width:%d em:%d font_h:%d font_s:%d" " line_h:%d line_s:%d spc_w:%d\n", k, wgml_fonts[k].default_width, wgml_fonts[k].em_base, wgml_fonts[k].font_height, wgml_fonts[k].font_space, wgml_fonts[k].line_height, wgml_fonts[k].line_space, wgml_fonts[k].spc_width ); } out_msg( "\npage top:%d bottom:%d left:%d right:%d lines:%d\n", g_page_top, g_page_bottom, g_page_left, g_page_right, lcmax ); out_msg( "page net depth:%d width:%d line height:%d char width:%d\n\n", g_net_page_depth, g_net_page_width, g_max_line_height, g_max_char_width ); } g_indent = 0; g_indentr = 0; init_nest_cb(); }
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 }