Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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 );
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
// 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;
}
Example #7
0
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, &current_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, &current_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 );
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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 );
}
Example #12
0
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 );
}
Example #13
0
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;
}