mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
23946ad264
Sat Jun 14 13:05:23 1997 Andreas Mohr <100.30936@germany.net> * [include/mmsystem.h] Avoided infinite loop in audio code when accessing WAVEOUTCAPS/WAVEINCAPS/MIDIOUTCAPS/AUXCAPS with rigid variable offsets (I applied WINE_PACKED). * [*/*] Added "WARNING:" and "ERROR:" to some printf's. Just grep for them with '-debugmsg +all'. * [multimedia/audio.c] [multimedia/mmsystem.c] Implemented wave callbacks: window and function callback. Fixed problem with WAVE_NotifyClient(). Misc fixes. * [windows/winhelp.c] Fixed problem with windows help telling "Help topic doesn't exist". But this problem still remains when using Winword. Wed Jun 11 09:14:20 1997 Alex Korobka <alex@trantor.pharm.sunysb.edu> * [wine.ini] New 'fonts' section format. Read documentation/fonts. * [controls/icontitle.c] [windows/winpos.c] [windows/nonclient.c] [windows/win.c] [include/win.h] Implemented icon titles. * [graphics/x11drv/xfont.c] [objects/font.c] [objects/dc.c] [include/x11drv.h] [include/x11font.h] [documentation/fonts] Rewrote font mapper from scratch. * [tools/fnt2bdf.c] Bug fixes. REPLACE FONTS CREATED BY THE PREVIOUS VERSIONS. * [windows/defwnd.c] [windows/nonclient.c] Word document window activation fix. * [windows/mdi.c] [windows/win.c] Replaced WCL lists with WIN_BuildWinArray(). Mon Jun 9 23:51:16 1997 Andrew Taylor <andrew@riscan.com> * [misc/error.c] [include/windows.h] [if1632/kernel.spec] Implemented LogParamError, LogError functions. Tue Jun 3 23:46:04 1997 Michiel van Loon <mfvl@xs4all.nl> * [include/mmsystem.h] [multimedia/audio.c] Constants for asynchronous play and record. * [multimedia/time.c] Filled in some empty functions. * [multimedia/mmsystem.c] Fixed bugs in waveOutOpen. * [multimedia/mmsystem.c] [multimedia/audio.c] Implemented Window Callback for wave output at least. * [files/file.c] Corrected bug in FileDosSetError. NULL pointer checking added. * [misc/spy.c] Added Multimedia messages to SPY_GetMsgName. Tue Jun 3 22:34:30 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [debugger/*.c][include/peexe.h][loader/*.c][tools/build.c] [tools/fnt2bdf.c][library/sup.c] IMAGE_* structs/defines changed fit better to SDK naming Don't load non-i386 PE executables. %fs should already be initialised for the FIRST loaded PE module. * [if1632/advapi.spec][win32/advapi.c] Some small stubs added to bring win32 setup.exe a bit farther. * [if1632/kernel32.spec][scheduler/process.c] Adapted to match win95 kernel32.dll ordinals (NT doesn't use ordinal import), some ordinal only exported functions added. * [if1632/relay.c] Added CallProc32W. * [misc/lzexpand.c] Fixed return values of GetExpandedName* (thanks to Andreas Mohr). * [objects/dib.c] Everything with more than 8 bit of color is a truecolor mode and doesn't have a colormap. Tue Jun 3 09:24:53 1997 John Harvey <john@division.co.uk> * [graphics/win16drv/font.c] [graphics/win16drv/init.c] [graphics/win16drv/prtdrv.c] [graphics/win16drv/text.c] [include/win16drv.h] Changed some structures that are passed to and from the 16 bit drivers to be allocated on the global heap. Implemented Escape(Control) 0x100 GetExtTextData properly to stop word from crashing. Postscript driver now prints on complete page instead of top left corner. Print spooling implemented. * [loader/module.c] MODULE_GetOrdinal changed char buffer to unsigned char to stop a loop that was happening when running the font control program from the control panel. Sun Jun 1 19:05:02 1997 Peter Schlaile <up9n@rz.uni-karlsruhe.de> * [include/miscemu.h] [loader/main.c] [msdos/ioports.c] Added support for direct io port access. Fri May 30 16:18:35 1997 David A. Cuthbert <dacut@dssc3353.ece.cmu.edu> * [misc/ver.c] Implemented VerFindFile16. Tue May 27 22:00:39 1997 Rick Richardson <rick@dgii.com> * [misc/comm.c] Fixed GetCommError and GetCommEventMask. Tue May 27 9:10:53 1997 Georg Beyerle <gbeyerle@awi-potsdam.de> * [scheduler/thread.c] Minor fix in thread database initialization. Mon May 26 19:46:34 1997 Philippe De Muyter <phdm@info.ucl.ac.be> * [objects/dc.c] In DC_SetupGCForPen, avoid to draw in GXxor mode with a 0 mask. Mon May 26 15:22:42 1997 Bruce Milner <Bruce.Milner@genetics.utah.edu> * [loader/pe_image.c] Add code for modules that co-reference each other. Photodex's agds.exe (cpic32) has two dll's that make calls into each other. Mon May 26 13:38:16 1997 Jody Goldberg <jodyg@idt.net> * [memory/virtual.c] Dont use stdio when reading /proc/self/maps. It causes problems with libc6. * [windows/dialog.c] Translate messages in IsDialogMessage when DLGC_WANTMESSAGE is used. Sun May 25 17:02:21 1997 Huw D M Davies <h.davies1@physics.oxford.ac.uk> * [objects/metafile.c] Resource cleanup in EnumMetaFile(). This was one reason Word was crashing after long periods of use. (Thanks to Chris Underhill for the logs) Sun May 25 14:59:33 1997 Jimen Ching <jching@flex.com> * [multimedia/mcistring.c] Initial support for compound MCI commands. Use case-insensitive compare for 'alias' and 'element' keywords. Fixed pointer copy of args keywords array.
610 lines
16 KiB
C
610 lines
16 KiB
C
/************************************************
|
|
*
|
|
* 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;
|
|
int g_outputPoints = 0;
|
|
|
|
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: fnt2bdf [-t] [-c charset] [-o basename] [input file]\n");
|
|
printf(" -c charset\tcharset name for OEM_CHARSET fonts\n");
|
|
printf(" -f basename\tbasic output filename\n");
|
|
printf(" -t \t\toutput files by point size instead of pixel height\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),
|
|
(g_outputPoints) ? return_data_value(dfShort, cpe_font_struct->hdr.dfPoints)
|
|
: return_data_value(dfShort, cpe_font_struct->hdr.dfPixHeight) );
|
|
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;
|
|
|
|
memcpy((char *) &cpe_font_struct.hdr, file_buffer, 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 + 1, 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 + 1,
|
|
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 + 1;
|
|
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("p-", fs);
|
|
|
|
/* average width */
|
|
|
|
fprintf( fs, "%d-", 10 * return_data_value(dfShort, cpe_font_struct->hdr.dfAvgWidth) );
|
|
|
|
/* charset */
|
|
|
|
switch( cpe_font_struct->hdr.dfCharSet[0] )
|
|
{
|
|
/* Microsoft just had to invent its own charsets! */
|
|
|
|
case ANSI_CHARSET: fputs("ansi-0\n", fs); break;
|
|
case GREEK_CHARSET: fputs("cp125-3\n", fs); break;
|
|
case TURKISH_CHARSET: fputs("iso8859-9", fs); break;
|
|
case HEBREW_CHARSET: fputs("cp125-5", fs); break;
|
|
case ARABIC_CHARSET: fputs("cp125-6", fs); break;
|
|
case BALTIC_CHARSET: fputs("cp125-7", fs); break;
|
|
case RUSSIAN_CHARSET: fputs("cp125-1", fs); break;
|
|
case EE_CHARSET: fputs("iso8859-2", fs); break;
|
|
case SYMBOL_CHARSET: fputs("misc-fontspecific\n", fs); break;
|
|
case SHIFTJIS_CHARSET: fputs("jisx0208.1983-0\n", fs); break;
|
|
case DEFAULT_CHARSET: fputs("iso8859-1\n", fs); break;
|
|
|
|
default:
|
|
case OEM_CHARSET:
|
|
if( !g_lpstrCharSet )
|
|
{
|
|
fputs("Undefined 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:
|
|
case 7:
|
|
case 8:
|
|
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
|
|
if( argv[i][1] == 't' )
|
|
{
|
|
g_outputPoints = 1;
|
|
continue;
|
|
}
|
|
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)
|
|
{
|
|
IMAGE_DOS_HEADER mz_header;
|
|
IMAGE_OS2_HEADER 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.e_magic);
|
|
|
|
if( s == IMAGE_DOS_SIGNATURE) /* looks like .dll file so far... */
|
|
{
|
|
s = return_data_value(dfShort, &mz_header.e_lfanew);
|
|
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 == IMAGE_NT_SIGNATURE)
|
|
{
|
|
fprintf( stderr, "Do not know how to handle 32-bit Windows DLLs.\n");
|
|
return FILE_ERROR;
|
|
}
|
|
else if ( s != IMAGE_OS2_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.e_lfanew);
|
|
|
|
if( size <= sizeof(NE_TYPEINFO) ) return FILE_ERROR;
|
|
retval = FILE_DLL;
|
|
}
|
|
else if( s == 0x300 || s == 0x200 ) /* maybe .fnt ? */
|
|
{
|
|
size = return_data_value(dfLong, (char*)&mz_header+2);
|
|
|
|
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;
|
|
}
|