l1text.c

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

C
491
字号
/****************************************************************************
*
*                            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!
*
****************************************************************************/


#include <math.h>
#include "gdefn.h"


extern float            sqrtf( float );
#pragma aux             sqrtf "*_";


/*  Definitions of local functions  */

static void     GetVectors( struct xycoord *, struct xycoord * );
static void     VecNormalize( short, float, float, struct xycoord * );
static void     GetAlignment( short *, short * );
static void     CalcSpacing( struct xycoord *, struct xycoord *,
                             struct xycoord * );
static void     CalcSides( struct xycoord *, struct xycoord *, struct xycoord *,
                           struct xycoord *, struct xycoord *, char _WCI86FAR * );
static void     CalcTranslation( struct xycoord *, struct xycoord *,
                           struct xycoord *, struct xycoord *, short, short );
static void     CalcCorners( struct xycoord _WCI86FAR *, struct xycoord *,
                             struct xycoord *, struct xycoord *, short, short );
static void     CalcNominal( struct xycoord *, struct xycoord *,
                             struct xycoord *, struct xycoord *,
                             struct xycoord *, char );
static short    Round( short, short );
static void     CalcConcat( struct xycoord _WCI86FAR *, struct xycoord *,
                            struct xycoord *, short, short, short, short );
static short    _CharWidth( char );


void _L1Text( short xpos, short ypos, char _WCI86FAR * str )
/*=====================================================

    Draw the character string pointed to by "str" at the position
    (xpos, ypos) using the current graphics text settings.  */

{
    short               hor;        /* horizontal alignment */
    short               vert;       /* vertical alignment   */
    struct xycoord      up;         /* character up vector  */
    struct xycoord      base;       /* character base line vector   */
    struct xycoord      prop;       /* adjustment vector for prop. font */
    struct xycoord      nommove;    /* nominal displacement vector  */
    struct xycoord      space;      /* spacing between characters   */
    struct xycoord      length;     /* horizontal side of parallelogram */
    struct xycoord      height;     /* vertical side of parallelogram   */
    struct xycoord      trans;      /* translation for parallelogram    */
    struct xycoord      corner[4];  /*  0 - lower left  */
                                    /*  1 - lower right */
                                    /*  2 - upper right */
                                    /*  3 - upper left  */
    if( *str == '\0' ) {
        _ErrorStatus = _GRNOOUTPUT;
        return;
    }
    if( _TextSettings.height == 0 || _TextSettings.width == 0 ) {
        _ErrorStatus = _GRNOOUTPUT;
        return;
    }
    GetVectors( &base, &up );
    GetAlignment( &hor, &vert );
    CalcSpacing( &base, &up, &space );
    CalcSides( &length, &height, &base, &up, &space, str );
    CalcTranslation( &trans, &length, &height, &up, hor, vert );
    CalcCorners( &corner, &length, &height, &trans, xpos, ypos );
    if( _TextSettings.txpath == _PATH_UP ) {    /* select proper corner for */
        xpos = corner[ 0 ].xcoord;              /* text starting position   */
        ypos = corner[ 0 ].ycoord;
    } else {
        xpos = corner[ _TextSettings.txpath ].xcoord;
        ypos = corner[ _TextSettings.txpath ].ycoord;
    }
    if( _TextSettings.txpath == _PATH_RIGHT ||
        _TextSettings.txpath == _PATH_LEFT ) {
        while( *str != '\0' ) {
            CalcNominal( &base, &up, &prop, &nommove, &space, *str );
            if( _TextSettings.txpath == _PATH_RIGHT ) {
                _HershDraw( *str, up.xcoord, -up.ycoord,
                            prop.xcoord, -prop.ycoord, xpos, ypos );
            } else {
                _HershDraw( *str, up.xcoord, -up.ycoord,
                            prop.xcoord, -prop.ycoord,
                            xpos-prop.xcoord, ypos+prop.ycoord );
            }
            xpos += nommove.xcoord;
            ypos -= nommove.ycoord;
            str++;
        }
    } else {                                        /* path is Up or DOWN   */
        if( _TextSettings.txpath == _PATH_DOWN ) {
            xpos -= up.xcoord;                      /* special increment*/
            ypos += up.ycoord;                      /* for path down    */
        }
        while( *str != '\0' ) {
            CalcNominal( &base, &up, &prop, &nommove, &space, *str );
            _HershDraw( *str, up.xcoord, -up.ycoord,
                        prop.xcoord, -prop.ycoord,
                        xpos + ( length.xcoord-prop.xcoord ) / 2,
                        ypos - ( length.ycoord-prop.ycoord ) / 2 );
            xpos += nommove.xcoord;
            ypos -= nommove.ycoord;
            str++;
        }
    }
    _RefreshWindow();
}

void _L1TXX( short xpos, short ypos, char _WCI86FAR * str,
/*========*/ struct xycoord _WCI86FAR * concat, struct xycoord _WCI86FAR * extent )

/*  Inquire the extents of the character drawing parallelogram and
    return the concatenation point. The concatenation point is the same
    as the drawing point if it cannot be calculated exactly.    */

{
    short               hor;        /* horizontal alignment */
    short               vert;       /* vertical alignment   */
    struct xycoord      up;         /* character up vector  */
    struct xycoord      base;       /* character base line vector   */
    struct xycoord      space;      /* spacing between characters   */
    struct xycoord      length;     /* horizontal side of parallelogram */
    struct xycoord      height;     /* vertical side of parallelogram   */
    struct xycoord      trans;      /* translation for parallelogram    */

    GetVectors( &base, &up );
    GetAlignment( &hor, &vert );
    CalcSpacing( &base, &up, &space );
    CalcSides( &length, &height, &base, &up, &space, str );
    CalcTranslation( &trans, &length, &height, &up, hor, vert );
    CalcCorners( extent, &length, &height, &trans, xpos, ypos );
    if( _TextSettings.txpath == _PATH_RIGHT ||
        _TextSettings.txpath == _PATH_LEFT ) {
        CalcConcat( concat, &length, &space, xpos, ypos, hor, vert );
    } else {
        CalcConcat( concat, &height, &space, xpos, ypos, hor, vert );
    }
}

static void GetVectors( struct xycoord * base, struct xycoord * up )
/*==================================================================

    Normalize the character up and base vectors to the character height
    and width respectively. The character up vector is made visually
    perpendicular to the character base vector. The character up vector
    is corrected by the screen aspect ratio so that it looks perpendicular
    to the character base vector on all devices. Assume that the
    width : height ratio of the physical dimensions of the screen is 4 : 3. */

{
    float           aspectratio;
    float           basex;
    float           basey;
    float           upx;
    float           upy;

    aspectratio = (float)( _CurrState->vc.numypixels << 2 ) /
                     (float)( _CurrState->vc.numxpixels * 3 );
    basex = (float) _TextSettings.basevectorx;
    basey = (float) _TextSettings.basevectory * aspectratio;
    upx = - (float) _TextSettings.basevectory;
    upy = basex * aspectratio;
    VecNormalize( _TextSettings.height, upx, upy, up );
    VecNormalize( _TextSettings.width, basex, basey, base );
}

static void VecNormalize( short scale, float dx, float dy, struct xycoord * vect )
/*================================================================================

    Normalize the vector (dx,dy) to scale and return in vect.   */

{
    float           factor;

    factor = (float) scale / sqrtf( dx * dx + dy * dy );
    vect->xcoord = dx * factor + roundoff( dx );              /* round result */
    vect->ycoord = dy * factor + roundoff( dy );
}

static void GetAlignment( short * hor, short * vert )
/*===================================================

    Remap the horizontal and vertical alignments to account for the
    defaults in the case of _NORMAL horizontal and/or vertical
    alignments */
{
    if ( _TextSettings.horizalign == _NORMAL ) {
        if( _TextSettings.txpath == _PATH_LEFT ) {
            *hor = _RIGHT;
        } else {
            *hor = _LEFT;
        }
    } else {
        *hor = _TextSettings.horizalign;
    }
    if( _TextSettings.vertalign == _NORMAL ) {
        if( _TextSettings.txpath == _PATH_UP ) {
            *vert = _BOTTOM;
        } else {
            *vert = _TOP;
        }
    } else {
        *vert = _TextSettings.vertalign;
    }
}

static void CalcSpacing( struct xycoord * base, struct xycoord * up,
/*====================*/ struct xycoord * space )

/*  Calculate the text spacing based on the text path.  */

{
    if( _TextSettings.txpath == _PATH_RIGHT ||
        _TextSettings.txpath == _PATH_LEFT ) {
        space->xcoord = (float)( base->xcoord * _TextSettings.spacing ) /

⌨️ 快捷键说明

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