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 + -
显示快捷键?