Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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 );
    }
}
Example #4
0
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
}
Example #5
0
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();
}
Example #6
0
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
}