fontsupp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,370 行 · 第 1/3 页
C
1,370 行
/****************************************************************************
*
* 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: Font file support (Windows .fon files, bitmap or vector).
*
****************************************************************************/
#include <string.h>
#include "gdefn.h"
#if !defined( _DEFAULT_WINDOWS )
#include "dotfunc.h"
typedef struct font_entry {
short type; // 0 == bitmap, 1 == vector
short ascent; // distance from top to baseline (in pixels)
short width; // character width in pixels, 0 == proportional
short height; // character height in pixels
short avgwidth; // average character width
short firstchar;
short lastchar;
char filename[ 81 ];
char facename[ 32 ];
char filler;
short version;
char _WCI86FAR *glyph_table;
char _WCI86FAR *bitmap_table;
long start_offset;
long glyph_offset;
long bitmap_offset;
unsigned short bitmap_size;
struct font_entry _WCI86FAR *link;
} FONT_ENTRY;
typedef _Packed struct windows_font {
short dfVersion;
long dfSize;
char dfCopyright[ 60 ];
short dfType; // 0 == bitmap, 1 == vector
short dfPoints;
short dfVertRes;
short dfHorizRes;
short dfAscent;
short dfInternalLeading;
short dfExternalLeading;
char dfItalic;
char dfUnderline;
char dfStrikeOut;
short dfWeight;
char dfCharSet;
short dfPixWidth;
short dfPixHeight;
char dfPitchAndFamily;
short dfAvgWidth;
short dfMaxWidth;
char dfFirstChar;
char dfLastChar;
char dfDefaultChar;
char dfBreakChar;
short dfWidthBytes;
long dfDevice;
long dfFace;
long dfBitsPointer;
long dfBitsOffset;
// additional fields have been omitted
} WINDOWS_FONT;
#endif
#define _UNDEFINED (-1)
#define _BITMAP 0
#define _STROKE 1
static short _XVecDir = 1; // text vector direction
static short _YVecDir = 0;
#if defined( _DEFAULT_WINDOWS )
#if defined( __WINDOWS__ )
static short StockFont = TRUE;
#else
// Font ID for OS2
#include< limits.h >
#define _STDFONTID 250
#endif
static int YVec2Degs( short YDir );
#else
#define _PROPORTIONAL 0
#define _FIXED 1
extern FONT_ENTRY _WCI86FAR _8x8Font;
static FONT_ENTRY _WCI86FAR *_CurFont = &_8x8Font;
static FONT_ENTRY _WCI86FAR *_FontList = NULL;
static float _XVecScale = 1; // magnification factor for
static float _YVecScale = 1; // stroke fonts
#endif
#if defined( __386__ )
#define MemCpy( dst, src, len ) memcpy( dst, src, len )
#define MemSet( s, c, len ) memset( s, c, len )
#define StrNICmp( s1, s2, len ) strnicmp( s1, s2, len )
#define StrCpy( dst, src ) strcpy( dst, src )
#define StrCmp( dst, src ) strcmp( dst, src )
#define StrLen( s ) strlen( s )
#else
#define MemCpy( dst, src, len ) _fmemcpy( dst, src, len )
#define MemSet( s, c, len ) _fmemset( s, c, len )
#define StrNICmp( s1, s2, len ) _fstrnicmp( s1, s2, len )
#define StrCpy( dst, src ) _fstrcpy( dst, src )
#define StrCmp( dst, src ) _fstrcmp( dst, src )
#define StrLen( s ) _fstrlen( s )
#endif
#if defined( __QNX__ )
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#if !defined( __386__ )
#include <sys/slib16.h>
#endif
#define tiny_ret_t int
#define tiny_handle_t int
#define TINY_ERROR( rc ) ( rc < 0 )
#define TINY_OK( rc ) ( rc >= 0 )
#define TINY_INFO( rc ) ( rc )
#define TinyOpen( f, m ) __open_slib( f, O_RDONLY, 0 )
#define FontSeekSet( f, o ) ( ( lseek( f, o, SEEK_SET ) == -1 ) ? -1 : 0 )
#define TinyRead( f, b, l ) read( f, b, l )
#define MyTinyFarRead( f, b, l ) read( f, b, l )
#define TinyClose( f ) close( f )
#else
#include "tinyio.h"
#if defined( __386__ )
#define MyTinyFarRead( h, b, l ) TinyRead( h, b, l )
#else
#define MyTinyFarRead( h, b, l ) TinyFarRead( h, b, l )
#endif
#define FontSeekSet( f, o ) TinySeek( f, o, TIO_SEEK_START )
#endif
#if !defined( _DEFAULT_WINDOWS )
static void _WCI86FAR *Alloc( unsigned short size )
//=================================================
{
#if defined( __QNX__ )
#if defined( __386__ )
return( malloc( size ) );
#else
return( MK_FP( qnx_segment_alloc( size ), 0 ) );
#endif
#else
#if defined( __386__ )
return( malloc( size ) );
#else
tiny_ret_t rc;
rc = TinyAllocBlock( ( size + 15 ) / 16 );
if( TINY_ERROR( rc ) ) {
return( NULL );
} else {
return( MK_FP( TINY_INFO( rc ), 0 ) );
}
#endif
#endif
}
static void Free( void _WCI86FAR *p )
//==============================
{
#if defined( __QNX__ )
#if defined( __386__ )
free( p );
#else
qnx_segment_free( FP_SEG( p ) );
#endif
#else
#if defined( __386__ )
free( p );
#else
TinyFreeBlock( FP_SEG( p ) );
#endif
#endif
}
static short seek_and_read( tiny_handle_t handle, long offset,
void _WCI86FAR *buf, unsigned short len )
/*===========================================================*/
{
tiny_ret_t rc;
short rlen;
if( TINY_ERROR( FontSeekSet( handle, offset ) ) ) {
_ErrorStatus = _GRINVALIDFONTFILE;
TinyClose( handle );
return( 0 );
}
rc = MyTinyFarRead( handle, buf, len );
if( TINY_ERROR( rc ) ) {
_ErrorStatus = _GRINVALIDFONTFILE;
TinyClose( handle );
return( 0 );
}
rlen = TINY_INFO( rc );
if( rlen != len ) {
_ErrorStatus = _GRINVALIDFONTFILE;
TinyClose( handle );
return( 0 );
}
return( 1 );
}
#define RS_HEADER ( 4 * sizeof( short ) )
#define RS_DESC ( 6 * sizeof( short ) )
static short addfont( long offset, tiny_handle_t handle, char *font_file )
//========================================================================
{
tiny_ret_t rc;
WINDOWS_FONT w_font;
FONT_ENTRY _WCI86FAR *curr;
char facename[ 32 ];
// printf( "found font at %lx\n", offset );
if( seek_and_read( handle, offset, &w_font, sizeof( WINDOWS_FONT ) ) == 0 ) {
return( 0 );
}
// read facename, can't use seek_and_read, since it might be at end of file
if( TINY_ERROR( FontSeekSet( handle, offset + w_font.dfFace ) ) ) {
_ErrorStatus = _GRINVALIDFONTFILE;
TinyClose( handle );
return( 0 );
}
rc = TinyRead( handle, facename, 32 );
if( TINY_ERROR( rc ) ) { // only check for error, not length
_ErrorStatus = _GRINVALIDFONTFILE;
TinyClose( handle );
return( 0 );
}
facename[ 31 ] = '\0';
curr = Alloc( sizeof( FONT_ENTRY ) );
if( curr == NULL ) {
_ErrorStatus = _GRINSUFFICIENTMEMORY;
TinyClose( handle );
return( 0 );
}
MemSet( curr, 0, sizeof( FONT_ENTRY ) );
curr->type = w_font.dfType & 1;
curr->ascent = w_font.dfAscent;
curr->width = w_font.dfPixWidth;
curr->height = w_font.dfPixHeight;
curr->avgwidth = w_font.dfAvgWidth;
curr->firstchar = w_font.dfFirstChar;
curr->lastchar = w_font.dfLastChar;
curr->version = w_font.dfVersion;
StrCpy( curr->filename, font_file );
StrCpy( curr->facename, facename );
curr->start_offset = offset;
offset += sizeof( WINDOWS_FONT );
if( curr->type == _BITMAP && ( offset & 1 ) ) {
++offset;
}
if( w_font.dfVersion == 0x0300 ) {
offset += 30; // size of extra stuff in V3.0 files
}
curr->glyph_offset = offset;
curr->bitmap_offset = w_font.dfBitsOffset;
curr->bitmap_size = w_font.dfSize - w_font.dfBitsOffset;
curr->link = _FontList;
_FontList = curr;
return( 1 );
}
static short readfontfile( char *font_file )
//==========================================
{
char sig;
long ne_offset;
short rs_offset;
short shift_count;
unsigned short type;
short count;
short i;
tiny_ret_t rc;
tiny_handle_t handle;
short table[ RS_DESC ];
// printf( "Found file '%s'\n", font_file );
rc = TinyOpen( font_file, TIO_READ );
if( TINY_ERROR( rc ) ) {
_ErrorStatus = _GRFONTFILENOTFOUND;
return( 0 );
}
handle = TINY_INFO( rc );
// check for signature of 0x40 at location 0x18
if( seek_and_read( handle, 0x18, &sig, sizeof( char ) ) == 0 ) {
return( 0 );
}
if( sig != 0x40 ) {
_ErrorStatus = _GRINVALIDFONTFILE;
TinyClose( handle );
return( 0 );
}
// get offset of NE header
if( seek_and_read( handle, 0x3c, &ne_offset, sizeof( long ) ) == 0 ) {
return( 0 );
}
// find start of resource table
if( seek_and_read( handle, ne_offset + 0x24, &rs_offset, sizeof( short ) ) == 0 ) {
return( 0 );
}
// get shift_count at start of resource table
ne_offset += rs_offset;
if( seek_and_read( handle, ne_offset, &shift_count, sizeof( short ) ) == 0 ) {
return( 0 );
}
// read entries in resource table, looking for font definitions
ne_offset += sizeof( short ); // skip over shift_count
for( ;; ) {
if( seek_and_read( handle, ne_offset, &table, RS_HEADER ) == 0 ) {
return( 0 );
}
type = table[ 0 ];
count = table[ 1 ];
if( type == 0 ) {
break;
} else if( type == 0x8008 ) { // font
for( i = 0; i < count; ++i ) {
if( seek_and_read( handle, ne_offset + RS_HEADER + i * RS_DESC, &table, RS_DESC ) == 0 ) {
return( 0 );
}
if( addfont( (long) table[ 0 ] << shift_count, handle, font_file ) == 0 ) {
return( 0 );
}
}
}
ne_offset += RS_HEADER + count * RS_DESC;
}
TinyClose( handle );
return( 1 );
}
static short GlyphWidth( FONT_ENTRY _WCI86FAR *curr )
//==============================================
// The format of the glyph table is as follows
// For _BITMAP fonts, there are two words: width, offset
// For _STROKE fonts, there are two words: offset, width
// Note: V3.0 _BITMAP fonts have a long offset, and
// fixed width _STROKE fonts do not include the width.
{
short width;
if( curr->type == _BITMAP ) {
if( curr->version == 0x200 ) {
width = 2 * sizeof( short );
} else {
width = sizeof( short ) + sizeof( long );
}
} else {
if( curr->width == 0 ) { // proportional
width = 2 * sizeof( short );
} else {
width = sizeof( short );
}
}
return( width );
}
short _WCI86FAR _CGRAPH _registerfonts( char _WCI86FAR *font_path )
//=======================================================
{
#if defined( __QNX__ )
DIR _WCI86FAR *dirp;
struct dirent _WCI86FAR *direntp;
#else
tiny_ret_t rc;
tiny_find_t fileinfo;
char _WCI86FAR *p;
#endif
short count;
FONT_ENTRY _WCI86FAR *curr;
short len;
char curr_file[ _MAX_PATH ];
_ErrorStatus = _GROK;
_unregisterfonts(); // free previous fonts, if any
StrCpy( curr_file, font_path ); // copy into near buffer
#if defined( __QNX__ )
#if !defined( __386__ ) // shared library returns far pointers
#define _dir _dir __far
#endif
dirp = opendir( curr_file );
#if !defined( __386__ )
#undef _dir
#endif
if( dirp == NULL ) {
_ErrorStatus = _GRFONTFILENOTFOUND;
return( -1 ); // No such file
} else {
for( ;; ) {
#if !defined( __386__ )
#define dirent dirent __far
#endif
direntp = readdir( dirp );
#if !defined( __386__ )
#undef dirent
#endif
if( direntp == NULL ) {
break;
}
len = StrLen( direntp->d_name );
if( len > 4 && StrCmp( direntp->d_name + len - 4, ".fon" ) == 0 ) {
StrCpy( curr_file, font_path );
len = strlen( curr_file );
curr_file[ len ] = '/';
StrCpy( curr_file + len + 1, direntp->d_name );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?