Release 961208
Sun Dec 8 14:51:57 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [configure.in]
Added check to see if the compiler supports building a DLL when
the --with-dll option is used.
* [controls/listbox.c]
Don't send LBN_SELCHANGE too often.
Added WM_CHARTOITEM support.
* [Make.rules.in] [library/Makefile.in]
Build winestub.o and link it with Winelib programs.
* [objects/text.c]
Added support for '&&' in DrawText().
* [tools/build.c]
Added -o option.
Sat Dec 7 12:07:07 1996 Andrew Lewycky <plewycky@oise.utoronto.ca>
* [win32/thread.c]
GetCurrentThread(): return -2 (current thread pseudo-handle).
GetCurrentThreadId(): return GetCurrentTask().
* [objects/font.c] [if1632/gdi32.spec]
GetTextExtentPoint32{A,W}Buggy(): for future bug-compatibility.
* [win32/findfile.c]
FindClose(): ignore INVALID_HANDLE_VALUE (like Win95).
* [windows/hook.c] [include/hook.h] [if1632/user.spec]
[if1632/user32.spec] [windows/focus.c] [windows/message.c]
[windows/nonclient.c] [windows/win.c] [windows/winpos.c]
Hooks rewritten to support Win32.
* [misc/winsock.c]
WINSOCK_select(): need to put sockets with errors into exceptfds.
WINSOCK_socket(): fix error return.
* [windows/win.c]
SetWindowWord(): call SetParent on GWW_HWNDPARENT.
Wed Dec 4 22:03:05 1996 Andrew Taylor <andrew@riscan.com>
* [files/dos_fs.c]
Check if buf is NULL before copying string in GetFullPathName32A().
Wed Dec 4 21:40:59 1996 Robert Pouliot <krynos@clic.net>
* [graphics/wing.c] [if1632/wing.spec]
Implemented many WinG functions, but some don't seem to
work correctly (probably due to the one not done).
Wed Dec 4 03:38:25 1996 Lee Jaekil <juria@puma.kaitech.re.kr>
* [misc/main.c]
Implemented a few more of the SystemParametersInfo() cases.
Sun Dec 1 22:30:00 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [controls/button.c]
Improved focus rectangle painting.
* [windows/dialog.c] [windows/defdlg.c]
Fixed IE3.0 problems with DWL_MSGRESULT.
Sun Dec 1 20:49:32 1996 Albrecht Kleine <kleine@ak.sax.de>
* [files/profile.c]
Changed error handling in PROFILE_SetString().
diff --git a/tools/fnt2bdf.c b/tools/fnt2bdf.c
new file mode 100644
index 0000000..f391b79
--- /dev/null
+++ b/tools/fnt2bdf.c
@@ -0,0 +1,584 @@
+/************************************************
+ *
+ * Extract fonts from .fnt or Windows DLL files
+ * and convert them to the .bdf format.
+ *
+ * Copyright 1994-1996 Kevin Carothers and Alex Korobka
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "windows.h"
+#include "fnt2bdf.h"
+#include "neexe.h"
+#include "module.h"
+
+#define MAP_BEG 118
+
+extern char* g_lpstrFileName;
+extern char* g_lpstrCharSet;
+
+#define FILE_ERROR 0
+#define FILE_DLL 1
+#define FILE_FNT 2
+
+/* global options */
+
+char* g_lpstrFileName = NULL;
+char* g_lpstrCharSet = NULL;
+char* g_lpstrInputFile = NULL;
+
+static char* errorDLLRead = "Unable to read Windows DLL.\n";
+static char* errorFNTRead = "Unable to read .FNT file.\n";
+static char* errorOpenFile = "Unable to open file.\n";
+static char* errorMemory = "Memory allocation error.\n";
+static char* errorFile = "Corrupt or invalid file.\n";
+static char* errorFontData = "Unable to parse font data: Error ";
+static char* errorEmpty = "No fonts found.\n";
+
+/* info */
+
+void usage()
+{
+ printf("Usage: font2bdf [-c charset] [-o basename] [input file]\n");
+ printf(" -c charset\tuse this charset name for OEM_CHARSET fonts\n");
+ printf(" -f basename\tbasic output filename\n");
+ printf(" input file\tMSWindows .fon, .fnt, .dll, or .exe file.\n");
+ printf("\nExample:\n fnt2bdf -c winsys vgasys.fnt\n\n");
+ exit(-1);
+}
+
+/* convert big-endian value to the local format */
+
+int return_data_value(enum data_types dtype, void * pChr)
+{
+int ret_val = 0;
+
+ switch(dtype) {
+ case (dfChar):
+ ret_val = (int) *(unsigned char *)pChr;
+ break;
+
+ case(dfShort):
+ ret_val = *(unsigned char *)pChr;
+ ret_val += (*((unsigned char *)pChr + 1) << 8);
+ break;
+
+ case(dfLong): {
+ int i;
+
+ for(i=3; i >= 0; i--) {
+ ret_val += *((unsigned char *)pChr + i) << (8*i);
+ }
+ break;
+ }
+ case(dfString):
+ }
+ return ret_val;
+}
+
+int make_bdf_filename(char* name, fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
+{
+int l_nameoffset = return_data_value(dfLong, cpe_font_struct->hdr.dfFace);
+char* lpChar;
+
+ if( !g_lpstrFileName )
+ {
+ if( !l_nameoffset ||
+ l_nameoffset > return_data_value(dfLong, cpe_font_struct->hdr.dfSize) + 1 )
+ return ERROR_DATA;
+ lpChar = (char*)(file_buffer + l_nameoffset);
+ }
+ else lpChar = g_lpstrFileName;
+
+ strcpy( name, lpChar );
+
+ while( (lpChar = strchr( name, ' ')) )
+ *lpChar = '-';
+
+ /* construct a filename from the font typeface, slant, weight, and size */
+
+ if( cpe_font_struct->hdr.dfItalic[0] ) strcat(name, "_i" );
+ else strcat(name, "_r" );
+
+ lpChar = name + strlen( name );
+ sprintf(lpChar, "%d-%d.bdf", return_data_value(dfShort, cpe_font_struct->hdr.dfWeight),
+ return_data_value(dfShort, cpe_font_struct->hdr.dfPoints) );
+ return 0;
+}
+
+/* parse FONT resource and write .bdf file */
+
+int parse_fnt_data(unsigned char* file_buffer, int length)
+{
+ fnt_fontS cpe_font_struct;
+ int ic=0, t;
+
+ bcopy(file_buffer, (char *) &cpe_font_struct.hdr, sizeof(fnt_hdrS));
+
+ /* check font header */
+
+ t = return_data_value(dfShort, cpe_font_struct.hdr.dfVersion);
+ if( t != 0x300 && t != 0x200) return ERROR_VERSION;
+
+ t = return_data_value(dfLong, cpe_font_struct.hdr.dfSize);
+ if( t > length ) return ERROR_SIZE;
+ else
+ {
+ /* set up the charWidth/charOffset structure pairs (dfCharTable)... */
+
+ int l_fchar = return_data_value(dfChar, cpe_font_struct.hdr.dfFirstChar),
+ l_lchar = return_data_value(dfChar, cpe_font_struct.hdr.dfLastChar);
+ int l_len = l_lchar-l_fchar, l_ptr = MAP_BEG;
+
+ /* malloc size = (# chars) * sizeof(WinCharS) */
+
+ if((cpe_font_struct.dfCharTable = (WinCharS *) calloc(sizeof(WinCharS), l_len)) == NULL)
+ return ERROR_MEMORY;
+
+ /* NOW, convert them all to UNIX (lton) notation... */
+
+ for(ic=0; ic < l_len; ic++) {
+ cpe_font_struct.dfCharTable[ic].charWidth = return_data_value(dfShort, &file_buffer[l_ptr]);
+ l_ptr += 2; /* bump by sizeof(short) */
+
+
+ if( return_data_value(dfShort, cpe_font_struct.hdr.dfVersion) == 0x200) {
+ cpe_font_struct.dfCharTable[ic].charOffset =
+ return_data_value(dfShort, &file_buffer[l_ptr]);
+ l_ptr += 2; /* bump by sizeof(long) */
+ }
+ else { /* Windows Version 3.0 type font */
+ cpe_font_struct.dfCharTable[ic].charOffset =
+ return_data_value(dfLong, &file_buffer[l_ptr]);
+ l_ptr += 4; /* bump by sizeof(long) */
+ }
+ }
+ t = dump_bdf(&cpe_font_struct, file_buffer);
+ free( cpe_font_struct.dfCharTable );
+ }
+ return t;
+}
+
+int dump_bdf( fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
+{
+ FILE* fp;
+ int ic;
+ int l_fchar = return_data_value(dfChar, cpe_font_struct->hdr.dfFirstChar),
+ l_lchar = return_data_value(dfChar, cpe_font_struct->hdr.dfLastChar);
+
+ int l_len = l_lchar-l_fchar,
+ l_hgt = return_data_value(dfChar, cpe_font_struct->hdr.dfPixHeight);
+ int l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
+ char l_filename[256];
+
+ if( (ic = make_bdf_filename(l_filename, cpe_font_struct, file_buffer)) )
+ return ic;
+
+ if((fp = fopen(l_filename, "w")) == (FILE *) 0)
+ {
+ fprintf(stderr, "Couldn't open \"%s\" for output.\n", l_filename);
+ return ERROR_FILE;
+ }
+
+ dump_bdf_hdr(fp, cpe_font_struct, file_buffer);
+
+ /* NOW, convert all chars to UNIX (lton) notation... */
+
+ for(ic=0; ic < l_len; ic++) {
+ int rowidx, l_span, /* how many char-cols wide is char? */
+ l_idx = cpe_font_struct->dfCharTable[ic].charOffset;
+
+ l_span = (int) (cpe_font_struct->dfCharTable[ic].charWidth-1)/8;
+
+ fprintf(fp, "STARTCHAR %d \n", ic);
+ fprintf(fp, "ENCODING %d\n", l_fchar);
+ fprintf(fp, "SWIDTH %d %d \n",
+ cpe_font_struct->dfCharTable[ic].charWidth*1000,
+ 0);
+
+ fprintf(fp, "DWIDTH %d %d \n",
+ cpe_font_struct->dfCharTable[ic].charWidth, 0);
+
+ fprintf(fp, "BBX %d %d %d %d\n",
+ cpe_font_struct->dfCharTable[ic].charWidth, l_hgt, 0,
+ l_ascent - l_hgt);
+
+ fprintf(fp, "BITMAP\n");
+ for(rowidx=0; rowidx < l_hgt; rowidx++) {
+ switch(l_span) {
+ case(0): /* 1-7 pixels wide font */
+ {
+ fprintf(fp, "%02X\n", (int) file_buffer[l_idx+rowidx]);
+ break;
+ }
+
+ case(1): /* 8-15 pixels wide font */
+ {
+ fprintf(fp, "%02X%02X",
+ (int) file_buffer[l_idx+rowidx], file_buffer[l_idx+l_hgt+rowidx]);
+ fprintf(fp, "\n");
+ break;
+ }
+
+ case(2): /* 16-23 pixels wide font */
+ {
+ fprintf(fp, "%02X%02X%02X",
+ file_buffer[l_idx+rowidx],
+ file_buffer[l_idx+l_hgt+rowidx],
+ file_buffer[l_idx+(2*l_hgt)+rowidx]);
+ fprintf(fp, "\n");
+ break;
+ }
+
+ case(3): /* 24-31 pixels wide font */
+ {
+ fprintf(fp, "%02X%02X%02X%02X",
+ file_buffer[l_idx+rowidx],
+ file_buffer[l_idx+l_hgt+rowidx],
+ file_buffer[l_idx+(2*l_hgt)+rowidx],
+ file_buffer[l_idx+(3*l_hgt)+rowidx]);
+ fprintf(fp, "\n");
+ break;
+ }
+ case(4): /* 32-39 */
+ {
+ fprintf(fp, "%02X%02X%02X%02X%02X",
+ file_buffer[l_idx+rowidx],
+ file_buffer[l_idx+l_hgt+rowidx],
+ file_buffer[l_idx+(2*l_hgt)+rowidx],
+ file_buffer[l_idx+(3*l_hgt)+rowidx],
+ file_buffer[l_idx+(4*l_hgt)+rowidx]);
+ fprintf(fp, "\n");
+ break;
+ }
+ default:
+ fclose(fp);
+ unlink(l_filename);
+ return ERROR_DATA;
+ }
+ }
+ fprintf(fp, "ENDCHAR\n");
+
+ l_fchar++; /* Go to next one */
+ }
+fprintf(fp, "ENDFONT\n");
+fclose(fp);
+return 0;
+}
+
+
+int dump_bdf_hdr(FILE* fs, fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
+{
+int l_fchar = return_data_value(dfChar, cpe_font_struct->hdr.dfFirstChar),
+ l_lchar = return_data_value(dfChar, cpe_font_struct->hdr.dfLastChar);
+int l_len = l_lchar - l_fchar;
+int l_nameoffset = return_data_value(dfLong, cpe_font_struct->hdr.dfFace);
+int l_cellheight = return_data_value(dfShort, cpe_font_struct->hdr.dfPixHeight);
+int l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
+
+ fprintf(fs, "STARTFONT 2.1\n");
+
+ /* Compose font name */
+
+ if( l_nameoffset &&
+ l_nameoffset < return_data_value(dfLong, cpe_font_struct->hdr.dfSize) )
+ {
+ int dpi, point_size;
+ char* lpFace = (char*)(file_buffer + l_nameoffset), *lpChar;
+ short tmWeight = return_data_value(dfShort, cpe_font_struct->hdr.dfWeight);
+
+ while((lpChar = strchr(lpFace, '-')) )
+ *lpChar = ' ';
+
+ fprintf(fs, "FONT -windows-%s-", lpFace );
+
+ if( tmWeight == 0 ) /* weight */
+ fputs("medium-", fs);
+ else if( tmWeight <= FW_LIGHT )
+ fputs("light-", fs);
+ else if( tmWeight <= FW_MEDIUM )
+ fputs("medium-", fs);
+ else if( tmWeight <= FW_DEMIBOLD )
+ fputs("demibold-", fs);
+ else if( tmWeight <= FW_BOLD )
+ fputs("bold-", fs);
+ else fputs("black-", fs);
+
+ if( cpe_font_struct->hdr.dfItalic[0] ) /* slant */
+ fputs("i-", fs);
+ else fputs("r-", fs);
+
+ /* style */
+
+ if( (cpe_font_struct->hdr.dfPitchAndFamily[0] & 0xF0) == FF_SWISS )
+ fputs("normal-sans-", fs);
+ else fputs("normal--", fs); /* still can be -sans */
+
+ /* y extents */
+
+ point_size = 10 * return_data_value(dfShort, cpe_font_struct->hdr.dfPoints );
+ dpi = (l_cellheight * 720) / point_size;
+
+ fprintf(fs, "%d-%d-%d-%d-", l_cellheight, 10*l_cellheight, 72, 72);
+ /* point_size, dpi, dpi); */
+
+ /* spacing */
+
+ if( return_data_value(dfShort, cpe_font_struct->hdr.dfPixWidth) ) fputs("c-", fs);
+ else fputs("m-", fs);
+
+ /* average width */
+
+ fprintf( fs, "%d-", 10 * return_data_value(dfShort, cpe_font_struct->hdr.dfAvgWidth) );
+
+ /* charset */
+
+ switch( cpe_font_struct->hdr.dfCharSet[0] )
+ {
+ case ANSI_CHARSET: fputs("ansi-0\n", fs); break;
+ default:
+ case DEFAULT_CHARSET: fputs("iso8859-1\n", fs); break;
+ case SYMBOL_CHARSET: fputs("misc-fontspecific\n", fs); break;
+ case SHIFTJIS_CHARSET: fputs("jisx0208.1983-0\n", fs); break;
+ case OEM_CHARSET:
+ if( !g_lpstrCharSet )
+ { fputs("Undefined OEM charset, use -c option.\n", stderr);
+ return ERROR_DATA; }
+ fprintf(fs, "%s\n", g_lpstrCharSet);
+ }
+ }
+ else return ERROR_DATA;
+
+ fprintf(fs, "SIZE %d %d %d\n",
+ l_cellheight,
+ return_data_value(dfShort, cpe_font_struct->hdr.dfHorizRes),
+ return_data_value(dfShort, cpe_font_struct->hdr.dfVertRes)); /* dfVertRes[2] */
+
+ fprintf(fs, "FONTBOUNDINGBOX %d %d %d %d\n",
+ return_data_value(dfShort, cpe_font_struct->hdr.dfMaxWidth),
+ return_data_value(dfChar, cpe_font_struct->hdr.dfPixHeight),
+ 0, l_ascent - l_cellheight );
+
+ fprintf(fs, "STARTPROPERTIES 4\n");
+
+ fprintf(fs, "FONT_ASCENT %d\n", l_ascent ); /* dfAscent[2] */
+ fprintf(fs, "FONT_DESCENT %d\n", l_cellheight - l_ascent );
+ fprintf(fs, "CAP_HEIGHT %d\n", l_ascent -
+ return_data_value(dfShort, cpe_font_struct->hdr.dfInternalLeading));
+ fprintf(fs, "DEFAULT_CHAR %d\n", return_data_value(dfShort, cpe_font_struct->hdr.dfDefaultChar));
+
+ fprintf(fs, "ENDPROPERTIES\n");
+
+ fprintf(fs, "CHARS %d\n", l_len);
+ return 0;
+}
+
+
+
+void parse_options(int argc, char **argv)
+{
+ int i;
+
+ switch( argc )
+ {
+ case 2:
+ g_lpstrInputFile = argv[1];
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ for( i = 1; i < argc - 1; i++ )
+ {
+ if( argv[i][0] != '-' ||
+ strlen(argv[i]) != 2 ) break;
+
+ if( argv[i][1] == 'c' ) { g_lpstrCharSet = argv[i+1]; }
+ else
+ if( argv[i][1] == 'f' ) { g_lpstrFileName = argv[i+1]; }
+ else
+ usage();
+
+ i++;
+ }
+ if( i == argc - 1 )
+ {
+ g_lpstrInputFile = argv[i];
+ break;
+ }
+ default: usage();
+ }
+
+}
+
+/* read file data and return file type */
+
+int get_resource_table(int fd, unsigned char** lpdata, int fsize)
+{
+ struct mz_header_s mz_header;
+ struct ne_header_s ne_header;
+ short s, offset, size, retval;
+
+
+ lseek( fd, 0, SEEK_SET );
+
+ if( read(fd, &mz_header, sizeof(mz_header)) != sizeof(mz_header) )
+ return FILE_ERROR;
+
+ s = return_data_value(dfShort, &mz_header.mz_magic);
+
+ if( s == MZ_SIGNATURE) /* looks like .dll file so far... */
+ {
+ s = return_data_value(dfShort, &mz_header.ne_offset);
+ lseek( fd, s, SEEK_SET );
+
+ if( read(fd, &ne_header, sizeof(ne_header)) != sizeof(ne_header) )
+ return FILE_ERROR;
+
+ s = return_data_value(dfShort, &ne_header.ne_magic);
+
+ if( s == PE_SIGNATURE)
+ {
+ fprintf( stderr, "Do not know how to handle 32-bit Windows DLLs.\n");
+ return FILE_ERROR;
+ }
+ else if ( s != NE_SIGNATURE) return FILE_ERROR;
+
+ s = return_data_value(dfShort, &ne_header.resource_tab_offset);
+ size = return_data_value(dfShort, &ne_header.rname_tab_offset);
+
+ if( size > fsize ) return FILE_ERROR;
+
+ size -= s;
+ offset = s + return_data_value(dfShort, &mz_header.ne_offset);
+
+ if( size <= sizeof(NE_TYPEINFO) ) return FILE_ERROR;
+ retval = FILE_DLL;
+ }
+ else if( s == 0x300 || s == 0x200 ) /* maybe .fnt ? */
+ {
+ size = return_data_value(dfLong, &mz_header.dont_care);
+
+ if( size != fsize ) return FILE_ERROR;
+ offset = 0;
+ retval = FILE_FNT;
+ }
+ else return FILE_ERROR;
+
+ *lpdata = (unsigned char*)malloc(size);
+
+ if( *lpdata )
+ {
+ lseek( fd, offset, SEEK_SET );
+ if( read(fd, *lpdata, size) != size )
+ { free( *lpdata ); *lpdata = NULL; }
+ }
+ return retval;
+}
+
+
+/* entry point */
+
+int main(int argc, char **argv)
+{
+ unsigned char* lpdata = NULL;
+ int fd;
+
+ parse_options( argc, argv);
+
+ if( (fd = open( g_lpstrInputFile, O_RDONLY)) )
+ {
+ int i;
+ struct stat file_stat;
+
+ fstat( fd, &file_stat);
+ i = get_resource_table( fd, &lpdata, file_stat.st_size );
+
+ switch(i)
+ {
+ case FILE_DLL:
+ if( lpdata )
+ {
+ int j, count = 0;
+ NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(lpdata + 2);
+ NE_NAMEINFO* pFontStorage = NULL;
+
+ while( (i = return_data_value(dfShort, &pTInfo->type_id)) )
+ {
+ j = return_data_value(dfShort, &pTInfo->count);
+ if( i == NE_RSCTYPE_FONT )
+ {
+ count = j;
+ pFontStorage = (NE_NAMEINFO*)(pTInfo + 1);
+ }
+
+ pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1) + j*sizeof(NE_NAMEINFO));
+ }
+ if( pFontStorage && count )
+ {
+ unsigned short size_shift = return_data_value(dfShort, lpdata);
+ unsigned char* lpfont = NULL;
+ unsigned offset;
+ unsigned length;
+
+ for( j = 0; j < count; j++, pFontStorage++ )
+ {
+ length = return_data_value(dfShort, &pFontStorage->length) << size_shift;
+ offset = return_data_value(dfShort, &pFontStorage->offset) << size_shift;
+
+ if( !(lpfont = (unsigned char*) realloc( lpfont, length )) )
+ {
+ fprintf(stderr, errorMemory );
+ free(lpdata);
+ return -1;
+ }
+
+ lseek( fd, offset, SEEK_SET );
+ if( read(fd, lpfont, length) != length )
+ {
+ fprintf(stderr, errorDLLRead );
+ free(lpdata); free(lpfont);
+ return -1;
+ }
+
+ if( (i = parse_fnt_data( lpfont, length )) )
+ fprintf(stderr, "%s%d\n", errorFontData, i );
+ }
+ free(lpfont); free(lpdata);
+ return 0;
+ }
+ else fprintf(stderr, errorEmpty );
+ free( lpdata );
+ }
+ else fprintf(stderr, errorDLLRead);
+ break;
+
+ case FILE_FNT:
+ if( lpdata )
+ {
+ if( (i = parse_fnt_data( lpdata, file_stat.st_size )) )
+ fprintf(stderr, "%s%d\n", errorFontData, i );
+
+ free( lpdata );
+ }
+ else fprintf(stderr, errorFNTRead);
+ break;
+
+ case FILE_ERROR:
+ fprintf(stderr, errorFile );
+
+ }
+ close(fd);
+ }
+ else fprintf(stderr, errorOpenFile );
+ return -1;
+}