window.c

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

C
1,263
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


/*
 Description:
 ============
    This module provides the cover interface from the WATCOM world
    library functions to the WINDOWS functions. These functions
    assume that Display_window has been setup.
*/

#include "icgr.h"
#include <string.h>

static int Width;
static int Height;
static int Win_x_start;
static int Win_y_start;

static float X_start;
static float Y_start;
static float X_width;
static float Y_width;
static float Win_width;
static float Win_height;

static int Log_x;
static int Log_y;

static char Dummy_text[]="M";

static text_dir Text_path;

static WPI_COLOUR       Set_color;
static int      Set_fill_style;
static int      Set_pen_style;
static wl_style Set_wl_style;
static wl_width Set_wl_width;
static bool     Set_end_marker;     // for wide lines

static bool     Save_style_on = FALSE;
static int      Save_style;

static HPEN             Old_pen;
static HBRUSH           Old_brush;

extern void _wsetendmarker(
/*************************/
    bool    end_marker
) {
    Set_end_marker = end_marker;
}

extern bool _wsetstylewrap(
/*************************/
    bool    save_style
) {
    bool    old_save;

    old_save = Save_style_on;
    Save_style_on = save_style;
    Save_style = 0;

    return( old_save );
}

WPI_COLOUR get_palette_color(
/***************************/
/* takes a 0 origin colour index, and returns the RGB for the current chart */

    int                 index
) {
    if( index >= Palette_size ) {
        index = Palette_size - 1;
    }

    return( Curr_palette[index] );
}

void _winitwindow(
/****************/
/* this must be called once before using any of the other window functions */

    WPI_RECT            *area
) {
    int                 left, right, top, bottom;

    _wpi_getintrectvalues( *area, &left, &top, &right, &bottom );
    Width = right - left;
    Height = bottom - top;
    Win_x_start = left;
    Win_y_start = top;

#if 0
    /* if Windows 3.0 worked intelligently, the following code would
       also work. But 'GetDeviceCaps' for metafiles hangs! */
    if( GetDeviceCaps( Win_dc, TECHNOLOGY ) == DT_METAFILE ) {
        /* metafiles don't have arbitary coords... assume square pixels */
        Aspect_ratio = ( float ) Height / (float) Width;
    } else {
        Aspect_ratio = ((float)Height / GetDeviceCaps( Win_dc, LOGPIXELSY ) ) /
                    ( (float)Width / GetDeviceCaps( Win_dc, LOGPIXELSX ) );
    }
#else
    if( Is_metafile ) {
        /* BIG assumption with metafiles: use LAST real device's Aspect
           ratio and logical information */
    } else {
        Log_x = _wpi_devicecapableinch( Win_dc, LOGPIXELSX );
        Log_y = _wpi_devicecapableinch( Win_dc, LOGPIXELSY );
        Aspect_ratio = ((float)Height / Log_y) / ((float)Width / Log_x);
        Pixel_aspect_ratio = (float)Log_y / (float)Log_x;
    }
#endif
}

void WINEXP cgr_aspect_ratio(
/***************************/
/* returns last display aspect ratio. MAKE SURE that cgr_display_chart
   was called once before calling this routine */

    float __far         *aspect
) {
    *aspect = Aspect_ratio;
}

void _wsetwindow(
/***************/
/* setup the window */

    float               xl,
    float               yb,
    float               xr,
    float               yt
) {
    Win_width =  xr - xl;
    Win_height =  yt - yb;
    X_start = xl;
    X_width = 1 / Win_width * Width;
    Y_start = yt;
    Y_width = 1 / Win_height * Height;

}

extern void convert_pt(
/*********************/

    float               x,
    float               y,
    int                 *dx,
    int                 *dy
) {
    *dx =  ( x - X_start ) * X_width + Win_x_start + .5;
    *dy =  ( Y_start - y ) * Y_width + Win_y_start + .5;
    *dy = _wpi_convertheight( *dy, (Win_y_start + Height), Win_y_start );
}

static int points_to_pixel(
/*************************/
/* returns pixels in vert. dir */

    int                 pts
) {
    return( (pts * Log_y) / 72 );
}

float max_psize(
/**************/
/* wierd function which takes percentage size and returns it, or up
   to a max governed by the max point size */

    float               psize,
    int                 max_points
) {
    int                 max_pixel;

    max_pixel = points_to_pixel( max_points );

    if( psize * Height > max_pixel ) {
        return( (float)max_pixel / Height );
    }

    return( psize );
}

WPI_FONT _wtextinit(
/******************/
/* initial text, pass back font handle for _wtextout */

    text_def            *text
) {
    WPI_LOGFONT         font;
    WPI_FONT            font_hld;
    BOOL                is_bold;
    int                 size;
    int                 match_no;

    _wpi_getdeffm( font );
    if( text->style & TEXT_SIZEABLE ) {
        _wpi_setfontsizeable( &font, TRUE );
    }
    if( text->not_set ) {
        _wpi_setfontfacename( &font, NULL );
    } else {
        _wpi_setfontfacename( &font, text->face_name );
    }

#if 0
    size = text->size%100;
    match_no = ((text->size-(text->size%100))/100);;
#else
    size = text->size;
    match_no = 0;
#endif
    _wpi_setfontpointsize( &font, size, points_to_pixel( text->size ),
                match_no );

    _wpi_settextcolor( Win_dc, get_palette_color( text->color - 1 ) );
    is_bold = text->style & TEXT_BOLD;
    _wpi_setfontbold( &font, is_bold );

    /* due to some wierd, undocumented bug in Windows, italics will
       not print on some devices unless the style booleans below
       are set to -1 (255)! We found this out by looking at what
       commdlg.dll returned in the LOGFONT. I don't understand,
       but leave it this way */
    _wpi_setfontitalic( &font, text->style & TEXT_ITALIC );
    _wpi_setfontunderline( &font, text->style & TEXT_UNDERLINE );
    _wpi_setfontstrikeout( &font, text->style & TEXT_STRIKEOUT );
    if( text->not_set ) {
        _wpi_setfontcharset( &font, ANSI_CHARSET );
        _wpi_setfontpitch( &font, DEFAULT_PITCH | FF_ROMAN );
    } else {
        _wpi_setfontcharset( &font, text->char_set );
        _wpi_setfontpitch( &font, text->pitchfamily );
    }

    _wpi_setfontprecision( &font, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS );
    _wpi_setfontquality( &font, DRAFT_QUALITY );

    _wpi_setfontescapement( &font, 0 );
    _wpi_setfontorientation( &font, 0 );

    _wpi_createfont( font, font_hld );

    return( font_hld );
}

void _wtextdone(
/**************/
/* make sure that the font is not currently selected into the display */
    WPI_FONT            font
) {
    _wpi_deletefont( font );
}

static void textdim(
/******************/

    char                *text_line,
    text_def            *text,
    int                 *width,
    int                 *height
) {
    WPI_FONT            font_hld;
    WPI_FONT            old_font;

    if( text_line == NULL ) {
        text_line = Dummy_text;
    }

    font_hld = _wtextinit( text );

    old_font = _wpi_selectfont( Win_dc, font_hld );

    _wpi_gettextextent( Win_dc, text_line, strlen( text_line ), width, height );

    _wpi_getoldfont( Win_dc, old_font );

    _wtextdone( font_hld );
}

static void textdim_font(
/***********************/
    char                *text_line,
    WPI_FONT            font_hld,
    int                 *width,
    int                 *height
) {
    WPI_FONT            old_font;

    if( text_line == NULL ) {
        text_line = Dummy_text;
    }

    font_hld = font_hld;                // unused in Windows
    old_font = _wpi_selectfont( Win_dc, font_hld );
    _wpi_gettextextent( Win_dc, text_line, strlen( text_line ), width, height );
    _wpi_getoldfont( Win_dc, old_font );
}

float _ptextwidth(
/****************/
/* return text width in percentage screen width of text line. If text_line
   is NULL, assume 1 character */

    char                *text_line,
    text_def            *text
) {
    int                 pix_width;
    int                 pix_height;
    float               width;

    textdim( text_line, text, &pix_width, &pix_height );

    width = (float)pix_width / Width;

    return( _min( width, 1.0 ) );
}

float _ptextmaxwidth(
/*******************/

    int                 num_chars,
    text_def            *text
) {
    char                *ptr;
    float               width;

    _new( ptr, num_chars + 1 );

    memset( ptr, 'M', num_chars );
    ptr[num_chars] = '\0';

    width = _ptextwidth( ptr, text );

    _free( ptr );

    return( width );
}

float _ptextheight(
/*****************/
/* return height of 1 char */

    text_def            *text
) {
    int                 pix_width;
    int                 pix_height;
    float               height;

    textdim( NULL, text, &pix_width, &pix_height );

    height = (float)pix_height / Height;

    return( _min( height, 1.0 ) );
}

float _wtextheight(
/*****************/
/* return text height in window coords of text line */

    text_def            *text
) {
    int                 pix_width;
    int                 pix_height;
    float               height;

    textdim( NULL, text, &pix_width, &pix_height );

    height = (float)pix_height / Height * Win_height;

    return( _min( height, Win_height ) );
}

extern float _wtextheight_font(
/*****************************/
/* returns text height in window coords using the given font */
    char *          text,
    WPI_FONT        font
) {
    int             pix_height;
    int             pix_width;
    float           height;

    if( Text_path == TEXT_VERTICAL ) {
        textdim_font( NULL, font, &pix_width, &pix_height );
        pix_height *= strlen( text );
    } else {
        textdim_font( text, font, &pix_width, &pix_height );
    }

⌨️ 快捷键说明

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