display.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 591 行 · 第 1/2 页

C
591
字号
    if( !EditFlags.RealTabs ) {
#ifndef __ALPHA__
        len = _inline_strlen( text );
#else
        len = strlen( text );
#endif
        otmp = tmp = StaticAlloc();
        ExpandTabsInABuffer( text, len, tmp, MaxLinem1 + 2 );
    } else {
        // leave the tabs alone ...
        // let tabbedTextExtent and tabbedTextOut do the rest.
        otmp = tmp = text;
    }

    // check out common text

    prev_col = start_col;
    if( EditFlags.RealTabs ){
        start_col = WinRealCursorPosition( otmp, start_col+1 ) -1;
    }

    tmp += start_col;
    display = tmp;


    // this section of code makes the ss blocks for this line.
    // it also compares the new blocks to the ones which existed
    // so that we can draw less ( although its not very good at it )
    x = 0;
    c_line = DCFindLine( c_line_no - 1, id );
    SSGetLanguageFlags( &( c_line->flags ) );
    ss_cache = c_line->ss;
    indent = 0;
    changed = TRUE;
    if( c_line->valid && c_line->start_col == start_col ) {
        /* do not redraw whatever is in common */
        old = c_line->text;

        SSDifBlock( ss_cache, otmp, start_col, line, line_no, &ssDifIndex );

        while( *old == *display ) {
            if( *old == 0 || indent == ssDifIndex ) break;
            old++;
            display++;
            indent++;
        }
        if( *old == *display && indent < ssDifIndex ) {
            changed = FALSE;
        } else {
            // jump ss_step to first block we are actually going to use
            ss_step = ss_cache;
            while( ss_step->end < indent ) {
                ss_step++;
            }
            // grap pixel offset of where to start next block
            x = 0;
            if( ss_step != ss_cache ) {
                x = ( ss_step - 1 )->offset;
            }
        }
    } else {
        SSDifBlock( ss_cache, otmp, start_col, line, line_no, &ssDifIndex );
        // start at beginning of line
        ss_step = ss_cache;
        x = 0;
    }


    // this section of code performs the drawing of the current line
    // to the display, by interpreting the ss_blocks.
    // The function MyTabbedTextOut prints one ss_block at a time,
    // and updates the position variables. The function
    // SetDrawingObjects updates the font colors and brush for the
    // current ss_block if they have changed.
    if( changed == TRUE ) {

        lastPos = indent -1;
        MoveToEx( hdc, x, y, NULL );
        p.x = x;
        SetTextAlign( hdc, TA_UPDATECP );
        lastFont  = -1;
        lastBack  = -1;
        lastFore  = -1;

        // check if we are at the last block OR the remainder
        // of the line is "BEYOND_TEXT" *sigh*
        while( ss_step->end != BEYOND_TEXT ) {

            // setup font and colors for next string.
            ts = &SEType[ ss_step->type ];
            funny_italic = SetDrawingObjects( hdc, ts );
            len = ss_step->end - lastPos;

            // MyTabbedTextOut is long and used in 2 places but needs so
            // many arguments maybe it should be inline.
            MyTabbedTextOut( hdc, &display, len, funny_italic,
                                &p, ts, &rect, id, otmp, y );

            // save pixel offset where next block is to start
            GetCurrentPositionEx( hdc, &p );
            ss_step->offset = p.x;

            if( p.x > rect.right ){
                // gone off the edge of the display!
                // put in dummy offsets for the rest of the blocks
                // and exit
                ss_step++;
                while( 1 ){
                    if( ss_step->end == BEYOND_TEXT ) break;
                    ss_step->offset = 10000;
                    ss_step++;
                }
                ss_step->offset = 10000;
                DCValidateLine( c_line, prev_col, tmp );
                if( !EditFlags.RealTabs ) {
                    StaticFree( otmp );
                }
                return( ERR_NO_ERR );
            }

            // advance to the next block
            ss_step++;
            lastPos += len;
        }

        // now "beyond text" but there still could be more "text"
        // if there is, display the rest of it!
        ts = &SEType[ ss_step->type ];
        funny_italic = SetDrawingObjects( hdc, ts );
        len = strlen( display );

        if( *display != '\0' ) {
            MyTabbedTextOut( hdc, &display, len, funny_italic,
                                &p, ts, &rect, id, otmp, y );
        }

        // if the previous line was longer than this one, blot it out.
        GetCurrentPositionEx( hdc, &p );
        rect.left += p.x;
        FillRect( hdc, &rect, thisBrush );

        // and set a dummy offset for this last block
        ss_step->offset = 10000;

        // line is now completely drawn. Validate it.
        DCValidateLine( c_line, prev_col, tmp );
    }

    if( !EditFlags.RealTabs ) {
        StaticFree( otmp );
    }
    return( ERR_NO_ERR );
}


#else
// unfortunately bitblting each line is considerably slower on standard
// vga, and at best only comparable to direct TextOut on Window accelerators
int DisplayLineInWindowWithSyntaxStyle( window_id id, int c_line_no,
    line *line, linenum line_no, char *text, int start_col,
    HDC hdc_wnd, HDC hdc_mem )
{
    char        *display, *old;
    char        *tmp, *otmp;
    dc          c_line;
    RECT        rect;
    int         width, height, len;
    int         x, y, indent;
    BOOL        changed;
    int         ssDifIndex;
    ss_block    *ss_cache, *ss_step;
    int         lastPos;
    int         lastFont, thisFont;
    int         lastFore, thisFore;
    int         lastBack, thisBack;
    type_style  *ts;
    POINT       p;

    if( !AllowDisplay || BAD_ID( id ) ) {
        return( ERR_NO_ERR );
    }

    // all font heights should be the same
    height = FontHeight( SEType[ SE_WHITESPACE ].font );
    width = WindowAuxInfo( CurrentWindow, WIND_INFO_WIDTH );
    y = ( c_line_no - 1 ) * height;
    GetClientRect( id, &rect );
    rect.top = y;
    rect.bottom = y + height;

    if( EditFlags.RealTabs ) {
#ifndef __ALPHA__
        len = _inline_strlen( text );
#else
        len = strlen( text );
#endif
        otmp = tmp = StaticAlloc();
        ExpandTabsInABuffer( text, len, tmp, MaxLinem1 + 2 );
    } else {
        otmp = tmp = text;
    }
    tmp += start_col;
    display = tmp;
    x = 0;
    c_line = DCFindLine( c_line_no - 1, id );
    SSGetLanguageFlags( &( c_line->flags ) );
    ss_cache = c_line->ss;
    indent = 0;
    changed = TRUE;
    if( c_line->valid && c_line->start_col == start_col ) {
        // do not redraw whatever is in common
        old = c_line->text;
        SSDifBlock( ss_cache, otmp, start_col, line, line_no, &ssDifIndex );
        while( *old == *display ) {
            if( *old == 0 || indent == ssDifIndex ) break;
            old++;
            display++;
            indent++;
        }
        if( *old == *display && indent < ssDifIndex ) {
            changed = FALSE;
        } else {
            // jump ss_step to first block we are actually going to use
            ss_step = ss_cache;
            while( ss_step->end < indent ) {
                ss_step++;
            }
            // grap pixel offset of where to start next block
            x = 0;
            if( ss_step != ss_cache ) {
                x = ( ss_step - 1 )->offset;
            }
        }
    } else {
        SSDifBlock( ss_cache, otmp, start_col, line, line_no, &ssDifIndex );
        // start at beginning of line
        ss_step = ss_cache;
        x = 0;
    }
    if( changed == TRUE ) {

        PatBlt( hdc_mem, 0, 0, 10000, 10000, PATCOPY );

        lastPos = indent - 1;
        MoveToEx( hdc_mem, x, 0, NULL );
        SetTextAlign( hdc_mem, TA_UPDATECP );
        lastFore = lastBack = lastFont = -1;
        while( ss_step->end != BEYOND_TEXT ) {
            ts = &SEType[ ss_step->type ];
            thisFore = ts->foreground;
            if( lastFore != thisFore ) {
                SetTextColor( hdc_mem, ColorRGB( thisFore ) );
                lastFore = thisFore;
            }
            thisBack = ts->background;
            if( lastBack != thisBack ) {
                SetBkColor( hdc_mem, ColorRGB( thisBack ) );
                lastBack = thisBack;
            }
            thisFont = ts->font;
            if( lastFont != thisFont ) {
                SelectObject( hdc_mem, FontHandle( thisFont ) );
                lastFont = thisFont;
            }
            len = ss_step->end - lastPos;
            TextOut( hdc_mem, 0, 0, display, len );
            // save pixel offset where next block is to start
            // ss_step->offset = LOWORD( GetCurrentPosition( hdc_mem ) );
            GetCurrentPositionEx( hdc, &p );            // BBB - Jan 6, 1994
            ss_step->offset = p.x;
            lastPos += len;
            display += len;
            ss_step++;
        }
        ts = &SEType[ ss_step->type ];
        if( *display != '\0' ) {
            SetTextColor( hdc_mem, ColorRGB( ts->foreground ) );
            SetBkColor( hdc_mem, ColorRGB( ts->background ) );
            SelectObject( hdc_mem, FontHandle( ts->font ) );
            TextOut( hdc_mem, 0, 0, display, strlen( display ) );
        }
        ss_step->offset = 10000;

        BitBlt( hdc_wnd, 0, y, width, height, hdc_mem, 0, 0, SRCCOPY );

        DCValidateLine( c_line, start_col, tmp );
    }

    if( EditFlags.RealTabs ) {
        StaticFree( otmp );
    }
    return( ERR_NO_ERR );
}
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?