591 lines
16 KiB
C
591 lines
16 KiB
C
/*++
|
|
|
|
Copyright (c) 1996-1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mkuff.c
|
|
|
|
Abstract:
|
|
|
|
|
|
Environment:
|
|
|
|
Windows NT PostScript driver
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
//
|
|
// Macros
|
|
//
|
|
|
|
DWORD gdwOutputFlags;
|
|
|
|
//
|
|
// Local function prototypes
|
|
//
|
|
|
|
BOOL
|
|
BiArgcheck(
|
|
IN INT iArgc,
|
|
IN CHAR **ppArgv,
|
|
IN OUT PWSTR pwstrInFileName,
|
|
IN OUT PWSTR pwstrOutFileName);
|
|
|
|
PBYTE
|
|
PCreateUFFFileHeader(
|
|
HANDLE hHeap,
|
|
PFILELIST pFileList,
|
|
PDWORD pdwUFFSize);
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
BYTE gcstrError1[] = "Usage: mkuff [-v] [Input Text file] [Output UFF file]\n";
|
|
BYTE gcstrError2[] = "mkuff: HeapCreate() failed\n.";
|
|
BYTE gcstrError3[] = "BGetInfo failed.\n";
|
|
BYTE gcstrError4[] = "Cannot create output file '%ws'.\n";
|
|
BYTE gcstrError5[] = "PCreateUFFFileHeader failed\n";
|
|
BYTE gcstrError6[] = "WriteFile fails: writes %ld bytes\n";
|
|
BYTE gcstrError8[] = "Cannot open file \"%ws\".\n";
|
|
|
|
|
|
INT __cdecl
|
|
main(
|
|
IN INT iArgc,
|
|
IN CHAR **ppArgv)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
main
|
|
|
|
Arguments:
|
|
|
|
iArgc - Number of parameters in the following
|
|
ppArgv - The parameters, starting with our name
|
|
|
|
Return Value:
|
|
|
|
Return error code
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
|
|
HANDLE hHeap, hInFile, hOutput;
|
|
PBYTE pInFile, pUFFFile;
|
|
DWORD dwInFileSize, dwI, dwUFFHeaderSize, dwWrittenSize, dwFileSize;
|
|
|
|
PWSTR wstrInFileName[FILENAME_SIZE];
|
|
PWSTR wstrOutFileName[FILENAME_SIZE];
|
|
|
|
FILELIST FileList;
|
|
DATA_HEADER DataHeader;
|
|
PCARTLIST pCartList;
|
|
PDATAFILE pDataTmp;
|
|
PDATAFILE pFontFile;
|
|
HANDLE hFontFile;
|
|
PBYTE pFontData;
|
|
|
|
if (gdwOutputFlags & OUTPUT_VERBOSE)
|
|
{
|
|
fprintf( stdout, "Start mkuff\n");
|
|
}
|
|
|
|
if (!BiArgcheck(iArgc, ppArgv, (PWSTR)wstrInFileName, (PWSTR)wstrOutFileName))
|
|
{
|
|
fprintf( stderr, gcstrError1);
|
|
return -1;
|
|
}
|
|
|
|
if (gdwOutputFlags & OUTPUT_VERBOSE)
|
|
{
|
|
fprintf( stdout, "InFile: %ws\nOutFile: %ws\n", wstrInFileName, wstrOutFileName);
|
|
}
|
|
|
|
//
|
|
// Heap Creation
|
|
//
|
|
|
|
if (!(hHeap = HeapCreate( HEAP_NO_SERIALIZE, 0x10000, 0x10000)))
|
|
{
|
|
fprintf( stderr, gcstrError2);
|
|
ERR(("CreateHeap failed: %d\n", GetLastError()));
|
|
return -2;
|
|
}
|
|
|
|
hInFile = MapFileIntoMemory((PWSTR)wstrInFileName,
|
|
(PVOID)&pInFile,
|
|
&dwInFileSize );
|
|
|
|
ZeroMemory(&FileList, sizeof(FILELIST));
|
|
|
|
if (!BGetInfo(hHeap, pInFile, dwInFileSize, &FileList))
|
|
{
|
|
fprintf( stderr, gcstrError3);
|
|
ERR(("CreateHeap failed: %d\n", GetLastError()));
|
|
return -3;
|
|
}
|
|
|
|
if (gdwOutputFlags & OUTPUT_VERBOSE)
|
|
{
|
|
PDATAFILE pFontFile;
|
|
PDATAFILE pTransFile;
|
|
PCARTLIST pCartList;
|
|
|
|
printf("\n");
|
|
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
|
|
printf("FileList\n");
|
|
|
|
pCartList = FileList.pCartList;
|
|
|
|
for (dwI = 0; dwI < FileList.dwCartridgeNum; dwI ++, pCartList = pCartList->pNext)
|
|
{
|
|
if (pCartList->pwstrCartName)
|
|
fprintf( stdout, "CartRidge(%d): ""%ws""\n", dwI, pCartList->pwstrCartName);
|
|
pFontFile = pCartList->pFontFile;
|
|
while( pFontFile )
|
|
{
|
|
fprintf( stdout, "FontFile(%d): %ws, FontName:%ws\n", pFontFile->rcID, pFontFile->pwstrFileName, pFontFile->pwstrDataName);
|
|
pFontFile = pFontFile->pNext;
|
|
}
|
|
|
|
pTransFile = pCartList->pTransFile;
|
|
while( pTransFile )
|
|
{
|
|
fprintf( stdout, "TransFile(%d): %ws\n", pTransFile->rcID, pTransFile->pwstrFileName);
|
|
pTransFile = pTransFile->pNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
UnmapFileFromMemory(hInFile);
|
|
|
|
pUFFFile = PCreateUFFFileHeader(hHeap, &FileList, &dwUFFHeaderSize);
|
|
|
|
if (pUFFFile == NULL)
|
|
{
|
|
fprintf( stderr, gcstrError5);
|
|
return -5;
|
|
|
|
}
|
|
|
|
hOutput = CreateFile((PWSTR)wstrOutFileName,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL );
|
|
|
|
if( hOutput == INVALID_HANDLE_VALUE )
|
|
{
|
|
fprintf( stderr, gcstrError4, wstrOutFileName);
|
|
return -4;
|
|
}
|
|
|
|
WriteFile( hOutput,
|
|
pUFFFile,
|
|
dwUFFHeaderSize,
|
|
&dwWrittenSize,
|
|
NULL );
|
|
|
|
if( dwWrittenSize != dwUFFHeaderSize)
|
|
{
|
|
fprintf( stderr, gcstrError6, dwWrittenSize);
|
|
return -6;
|
|
}
|
|
|
|
//
|
|
// Open font file and write data
|
|
//
|
|
|
|
pCartList = FileList.pCartList;
|
|
while (pCartList)
|
|
{
|
|
pDataTmp = pCartList->pFontFile;
|
|
while (pDataTmp)
|
|
{
|
|
hFontFile = MapFileIntoMemory(pDataTmp->pwstrFileName,
|
|
(PVOID)&pFontData,
|
|
&dwFileSize );
|
|
|
|
DataHeader.dwSignature = pDataTmp->dwSignature;
|
|
DataHeader.wSize = sizeof(DATA_HEADER);
|
|
DataHeader.wDataID = (WORD)pDataTmp->rcID;
|
|
DataHeader.dwDataSize = (WORD)dwFileSize;
|
|
DataHeader.dwReserved = 0;
|
|
|
|
if (hFontFile)
|
|
{
|
|
WriteFile( hOutput,
|
|
&DataHeader,
|
|
sizeof(DATA_HEADER),
|
|
&dwWrittenSize,
|
|
NULL);
|
|
|
|
if( dwWrittenSize != sizeof(DATA_HEADER))
|
|
{
|
|
fprintf( stderr, gcstrError6, dwWrittenSize);
|
|
return -6;
|
|
}
|
|
|
|
WriteFile( hOutput,
|
|
pFontData,
|
|
dwFileSize,
|
|
&dwWrittenSize,
|
|
NULL);
|
|
|
|
if( dwWrittenSize != dwFileSize)
|
|
{
|
|
fprintf( stderr, gcstrError6, dwWrittenSize);
|
|
return -6;
|
|
}
|
|
|
|
UnmapFileFromMemory(hFontFile);
|
|
}
|
|
else
|
|
break;
|
|
|
|
pDataTmp = pDataTmp->pNext;
|
|
}
|
|
pDataTmp = pCartList->pTransFile;
|
|
while (pDataTmp)
|
|
{
|
|
hFontFile = MapFileIntoMemory(pDataTmp->pwstrFileName,
|
|
(PVOID)&pFontData,
|
|
&dwFileSize );
|
|
DataHeader.dwSignature = pDataTmp->dwSignature;
|
|
DataHeader.wSize = sizeof(DATA_HEADER);
|
|
DataHeader.wDataID = (WORD)pDataTmp->rcID;
|
|
DataHeader.dwDataSize = (WORD)dwFileSize;
|
|
DataHeader.dwReserved = 0;
|
|
|
|
if (hFontFile)
|
|
{
|
|
WriteFile( hOutput,
|
|
&DataHeader,
|
|
sizeof(DATA_HEADER),
|
|
&dwWrittenSize,
|
|
NULL);
|
|
|
|
if( dwWrittenSize != sizeof(DATA_HEADER))
|
|
{
|
|
fprintf( stderr, gcstrError6, dwWrittenSize);
|
|
return -6;
|
|
}
|
|
WriteFile( hOutput,
|
|
pFontData,
|
|
dwFileSize,
|
|
&dwWrittenSize,
|
|
NULL);
|
|
|
|
if( dwWrittenSize != dwFileSize)
|
|
{
|
|
fprintf( stderr, gcstrError6, dwWrittenSize);
|
|
return -6;
|
|
}
|
|
|
|
UnmapFileFromMemory(hFontFile);
|
|
}
|
|
else
|
|
break;
|
|
|
|
pDataTmp = pDataTmp->pNext;
|
|
}
|
|
|
|
pCartList = pCartList->pNext;
|
|
}
|
|
|
|
CloseHandle(hOutput);
|
|
|
|
HeapDestroy(hHeap);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
BiArgcheck(
|
|
IN INT iArgc,
|
|
IN CHAR **ppArgv,
|
|
IN OUT PWSTR pwstrInFileName,
|
|
IN OUT PWSTR pwstrOutFileName)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
iArgcheck
|
|
|
|
Arguments:
|
|
|
|
iArgc - Number of parameters in the following
|
|
ppArgv - The parameters, starting with our name
|
|
pwstrInFileName -
|
|
pwstrOutFileName -
|
|
|
|
Return Value:
|
|
|
|
If TRUE, function succeeded. Othewise FALSE.
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
INT iI;
|
|
INT iRet;
|
|
|
|
if (iArgc > 4 || iArgc < 3)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (iArgc == 4)
|
|
{
|
|
gdwOutputFlags |= OUTPUT_VERBOSE;
|
|
ppArgv++;
|
|
}
|
|
|
|
ppArgv++;
|
|
iRet = MultiByteToWideChar(CP_ACP, 0, *ppArgv, strlen(*ppArgv), pwstrInFileName, FILENAME_SIZE);
|
|
*(pwstrInFileName + iRet) = (WCHAR)NULL;
|
|
ppArgv++;
|
|
iRet = MultiByteToWideChar(CP_ACP, 0, *ppArgv, strlen(*ppArgv), pwstrOutFileName, FILENAME_SIZE);
|
|
*(pwstrOutFileName + iRet) = (WCHAR)NULL;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
PBYTE
|
|
PCreateUFFFileHeader(
|
|
HANDLE hHeap,
|
|
PFILELIST pFileList,
|
|
PDWORD pdwUFFHeaderSize)
|
|
{
|
|
HANDLE hFontFile;
|
|
PDATAFILE pFontFile, pTransFile;
|
|
PCARTLIST pCartList;
|
|
PDATAFILE pDataTmp;
|
|
PUFF_FILEHEADER pUFFHeader;
|
|
PUFF_FONTDIRECTORY pUFFFontDir, pFirstFontDir;
|
|
|
|
PBYTE pFontData;
|
|
DWORD dwNumOfFontNameChars, dwNumOfData, dwNumOfFonts, dwNumOfTrans, dwUFFHeaderSize, dwFileSize, dwNumOfCartNameChars, dwI;
|
|
DWORD dwOffset, offCartridgeName;
|
|
PWSTR pwstrCartNameBuf, pwstrFontNameBuf;
|
|
|
|
*pdwUFFHeaderSize = 0;
|
|
|
|
dwNumOfFontNameChars = dwNumOfCartNameChars = dwNumOfFonts = dwNumOfTrans = 0;
|
|
pCartList = pFileList->pCartList;
|
|
while (pCartList)
|
|
{
|
|
pDataTmp = pCartList->pFontFile;
|
|
while (pDataTmp)
|
|
{
|
|
dwNumOfFontNameChars += 1 + wcslen(pDataTmp->pwstrDataName);
|
|
pDataTmp = pDataTmp->pNext;
|
|
dwNumOfFonts ++;
|
|
}
|
|
|
|
pDataTmp = pCartList->pTransFile;
|
|
while (pDataTmp)
|
|
{
|
|
pDataTmp = pDataTmp->pNext;
|
|
dwNumOfTrans ++;
|
|
}
|
|
|
|
if (pCartList->pwstrCartName)
|
|
dwNumOfCartNameChars += 1 + wcslen(pCartList->pwstrCartName);
|
|
|
|
pCartList = pCartList->pNext;
|
|
}
|
|
|
|
dwNumOfData = dwNumOfFonts + dwNumOfTrans;
|
|
|
|
dwUFFHeaderSize = sizeof(UFF_FILEHEADER) +
|
|
sizeof(UFF_FONTDIRECTORY) * dwNumOfFonts +
|
|
dwNumOfCartNameChars * sizeof(WCHAR) +
|
|
dwNumOfFontNameChars * sizeof(WCHAR);
|
|
|
|
pUFFHeader = (PUFF_FILEHEADER)HeapAlloc(hHeap, 0, dwUFFHeaderSize);
|
|
|
|
if (pUFFHeader == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Fill in header.
|
|
//
|
|
|
|
pUFFHeader->dwSignature = UFF_FILE_MAGIC;
|
|
pUFFHeader->dwVersion = UFF_VERSION_NUMBER;
|
|
pUFFHeader->dwSize = sizeof(UFF_FILEHEADER);
|
|
pUFFHeader->nFonts = dwNumOfFonts;
|
|
pUFFHeader->nGlyphSets = dwNumOfTrans;
|
|
pUFFHeader->nVarData = 0;
|
|
pUFFHeader->offFontDir = sizeof(UFF_FILEHEADER);
|
|
pUFFHeader->dwFlags = 0;
|
|
pUFFHeader->dwReserved[0] = 0;
|
|
pUFFHeader->dwReserved[1] = 0;
|
|
pUFFHeader->dwReserved[2] = 0;
|
|
pUFFHeader->dwReserved[3] = 0;
|
|
|
|
|
|
//
|
|
// Fill in UFF_FONTDIRECTORY
|
|
//
|
|
// ------------------
|
|
// UFF_FONTHEADER
|
|
// ------------------
|
|
// UFF_FONTDIRECTORY * (Number of fonts)
|
|
// ------------------
|
|
// Cartridge name
|
|
// ------------------
|
|
// Font name
|
|
// ------------------
|
|
// First cartridge font data
|
|
// ------------------
|
|
// First cartridge glyph data
|
|
// ------------------
|
|
// Second cartridge font data
|
|
// ------------------
|
|
// Second cartridge glyph data
|
|
// ------------------
|
|
//
|
|
|
|
pUFFFontDir = (PUFF_FONTDIRECTORY)(pUFFHeader + 1);
|
|
pwstrCartNameBuf = (PWSTR)(pUFFFontDir + dwNumOfFonts);
|
|
pwstrFontNameBuf = pwstrCartNameBuf + dwNumOfCartNameChars;
|
|
pCartList = pFileList->pCartList;
|
|
dwOffset = sizeof(UFF_FILEHEADER) +
|
|
sizeof(UFF_FONTDIRECTORY) * dwNumOfFonts +
|
|
dwNumOfCartNameChars * sizeof(WCHAR) +
|
|
dwNumOfFontNameChars * sizeof(WCHAR);
|
|
|
|
while(pCartList)
|
|
{
|
|
pFontFile = pCartList->pFontFile;
|
|
pTransFile = pCartList->pTransFile;
|
|
pFirstFontDir = pUFFFontDir;
|
|
if (pCartList->pwstrCartName)
|
|
{
|
|
offCartridgeName = (PBYTE)pwstrCartNameBuf - (PBYTE)pUFFHeader;
|
|
wcscpy(pwstrCartNameBuf, pCartList->pwstrCartName);
|
|
pwstrCartNameBuf += wcslen(pCartList->pwstrCartName) + 1;
|
|
}
|
|
else
|
|
offCartridgeName = (DWORD)NULL;
|
|
|
|
while (pFontFile)
|
|
{
|
|
hFontFile = MapFileIntoMemory(pFontFile->pwstrFileName,
|
|
(PVOID)&pFontData,
|
|
&dwFileSize );
|
|
if (hFontFile)
|
|
{
|
|
pFontFile->dwSize = dwFileSize;
|
|
|
|
if (1)
|
|
{
|
|
pFontFile->dwSignature = DATA_IFI_SIG;
|
|
pFontFile->rcTrans = ((FI_DATA_HEADER*)pFontData)->u.sCTTid;
|
|
}
|
|
else
|
|
{
|
|
pFontFile->dwSignature = DATA_UFM_SIG;
|
|
pFontFile->rcTrans = (SHORT)((UNIFM_HDR*)pFontData)->lGlyphSetDataRCID;
|
|
}
|
|
|
|
UnmapFileFromMemory(hFontFile);
|
|
}
|
|
else
|
|
return NULL;
|
|
|
|
|
|
pUFFFontDir->dwSignature = FONT_REC_SIG;
|
|
pUFFFontDir->wSize = sizeof(UFF_FONTDIRECTORY);
|
|
pUFFFontDir->wFontID = (WORD)pFontFile->rcID;
|
|
pUFFFontDir->sGlyphID = (SHORT)pFontFile->rcTrans;
|
|
pUFFFontDir->wFlags = 0;
|
|
pUFFFontDir->dwInstallerSig = WINNT_INSTALLER_SIG;
|
|
|
|
if (pFontFile->pwstrDataName)
|
|
{
|
|
pUFFFontDir->offFontName = (PBYTE)pwstrFontNameBuf - (PBYTE)pUFFHeader;
|
|
wcscpy(pwstrFontNameBuf, pFontFile->pwstrDataName);
|
|
pwstrFontNameBuf += wcslen(pFontFile->pwstrDataName) + 1;
|
|
}
|
|
else
|
|
pUFFFontDir->offFontName = (DWORD)NULL;
|
|
|
|
|
|
pUFFFontDir->offCartridgeName = offCartridgeName;
|
|
pUFFFontDir->offFontData = dwOffset;
|
|
pUFFFontDir->offGlyphData = 0;
|
|
pUFFFontDir->offVarData = 0;
|
|
pUFFFontDir++;
|
|
|
|
dwOffset += pFontFile->dwSize + sizeof(DATA_HEADER);
|
|
pFontFile = pFontFile->pNext;
|
|
}
|
|
while (pTransFile)
|
|
{
|
|
hFontFile = MapFileIntoMemory(pTransFile->pwstrFileName,
|
|
(PVOID)&pFontData,
|
|
&dwFileSize );
|
|
if (1)
|
|
{
|
|
pTransFile->dwSignature = DATA_RLE_SIG;
|
|
}
|
|
else
|
|
pTransFile->dwSignature = DATA_GTT_SIG;
|
|
|
|
if (hFontFile)
|
|
{
|
|
pTransFile->dwSize = dwFileSize;
|
|
while (pFirstFontDir < pUFFFontDir)
|
|
{
|
|
if (pFirstFontDir->sGlyphID == (SHORT)pTransFile->rcID)
|
|
pFirstFontDir->offGlyphData = dwOffset;
|
|
pFirstFontDir ++;
|
|
}
|
|
dwOffset += dwFileSize + sizeof(DATA_HEADER);
|
|
|
|
UnmapFileFromMemory(hFontFile);
|
|
}
|
|
else
|
|
return NULL;
|
|
|
|
pTransFile = pTransFile->pNext;
|
|
}
|
|
|
|
pCartList = pCartList->pNext;
|
|
}
|
|
|
|
if (gdwOutputFlags & OUTPUT_VERBOSE)
|
|
{
|
|
BDumpUFF(pUFFHeader);
|
|
}
|
|
|
|
*pdwUFFHeaderSize = dwUFFHeaderSize;
|
|
|
|
return (PBYTE)pUFFHeader;
|
|
}
|
|
|