|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
writentf.c
Abstract:
Write a NTF file.
Environment:
Windows NT PostScript driver.
Revision History:
07/08/98 -ksuzuki- Modified to support -v(verbose) and -o(optimize) options.
11/21/96 -slam- Created.
dd-mm-yy -author- description
--*/
#include "writentf.h"
extern bVerbose; extern bOptimize;
int __cdecl compareGlyphSet(const void *elem1, const void *elem2) { PGLYPHSETDATA *p1; PGLYPHSETDATA *p2; PGLYPHSETDATA pGlyphSet1; PGLYPHSETDATA pGlyphSet2; DWORD hashValue1, hashValue2;
p1 = (PGLYPHSETDATA*)elem1; p2 = (PGLYPHSETDATA*)elem2;
pGlyphSet1 = *p1; pGlyphSet2 = *p2;
hashValue1 = HashKeyword(MK_PTR(pGlyphSet1, dwGlyphSetNameOffset)); hashValue2 = HashKeyword(MK_PTR(pGlyphSet2, dwGlyphSetNameOffset));
if (hashValue1 == hashValue2) return(0); else if (hashValue1 < hashValue2) return(-1); else return(1); }
int __cdecl compareFontMtx(const void *elem1, const void *elem2) { PNTM *p1; PNTM *p2; PNTM pNTM1; PNTM pNTM2; DWORD hashValue1, hashValue2;
p1 = (PNTM*)elem1; p2 = (PNTM*)elem2;
pNTM1 = *p1; pNTM2 = *p2;
hashValue1 = HashKeyword(MK_PTR(pNTM1, dwFontNameOffset)); hashValue2 = HashKeyword(MK_PTR(pNTM2, dwFontNameOffset));
if (hashValue1 == hashValue2) return(0); else if (hashValue1 < hashValue2) return(-1); else return(1); }
BOOL WriteNTF( IN PWSTR pwszNTFFile, IN DWORD dwGlyphSetCount, IN DWORD dwGlyphSetTotalSize, IN PGLYPHSETDATA *pGlyphSetData, IN DWORD dwFontMtxCount, IN DWORD dwFontMtxTotalSize, IN PNTM *pNTM ) { HANDLE hNTFFile; NTF_FILEHEADER fileHeader; PNTF_GLYPHSETENTRY pGlyphSetEntry; PNTF_FONTMTXENTRY pFontMtxEntry; ULONG ulGlyphSetEntrySize; ULONG ulFontMtxEntrySize; ULONG ulByteWritten; ULONG i, j; DWORD dwOffset; DWORD dwGlyphSetCount2, dwGlyphSetTotalSize2; PGLYPHSETDATA pgsd; DWORD dwEofMark = NTF_EOF_MARK;
dwGlyphSetCount2 = dwGlyphSetTotalSize2 = 0;
//
// Count the number of glyphsets necessary or referenced and their total
// size. When optimization option is specified, don't count the glyphsets
// without reference mark.
//
for (i = 0; i < dwGlyphSetCount; i++) { if (!bOptimize || pGlyphSetData[i]->dwReserved[0]) { dwGlyphSetCount2++; dwGlyphSetTotalSize2 += pGlyphSetData[i]->dwSize; } }
if (!bOptimize && (dwGlyphSetTotalSize != dwGlyphSetTotalSize2)) { ERR(("WriteNTF:total size mismatch on optimization\n")); return FALSE; }
if (bVerbose) { printf("Number of glyphset:%ld(total:%ld)\n", dwGlyphSetCount, dwGlyphSetTotalSize); if (bOptimize) { printf("Number of glyphset referenced:%ld(total:%ld)\n", dwGlyphSetCount2, dwGlyphSetTotalSize2); }
printf("Number of font matrix:%ld(total:%ld)\n", dwFontMtxCount, dwFontMtxTotalSize);
printf("\n"); }
// Fill in NTF file header.
fileHeader.dwSignature = NTF_FILE_MAGIC; fileHeader.dwDriverType = NTF_DRIVERTYPE_PS; fileHeader.dwVersion = NTF_VERSION_NUMBER;
for (i = 0; i < 5; i++) fileHeader.dwReserved[i] = 0;
fileHeader.dwGlyphSetCount = dwGlyphSetCount2; fileHeader.dwFontMtxCount = dwFontMtxCount;
ulGlyphSetEntrySize = dwGlyphSetCount2 * sizeof(NTF_GLYPHSETENTRY); ulFontMtxEntrySize = dwFontMtxCount * sizeof(NTF_FONTMTXENTRY);
fileHeader.dwGlyphSetOffset = sizeof(NTF_FILEHEADER);
fileHeader.dwFontMtxOffset = fileHeader.dwGlyphSetOffset + ulGlyphSetEntrySize;
// Fill in glyph set entries.
qsort(pGlyphSetData, dwGlyphSetCount, sizeof(PGLYPHSETDATA), compareGlyphSet);
pGlyphSetEntry = MemAllocZ(ulGlyphSetEntrySize); if (!pGlyphSetEntry) { ERR(("WriteNTF:MemAllocZ\n")); return(FALSE); }
dwOffset = fileHeader.dwFontMtxOffset + ulFontMtxEntrySize;
for (i = j = 0; i < dwGlyphSetCount; i++) { pgsd = pGlyphSetData[i];
// If no refernce mark is set with optimization option, ignore this
// glyphset data.
if (bOptimize && !(pgsd->dwReserved[0])) { pgsd = NULL; }
if (pgsd) { pGlyphSetEntry[j].dwNameOffset = dwOffset + pgsd->dwGlyphSetNameOffset; pGlyphSetEntry[j].dwHashValue = HashKeyword(MK_PTR(pgsd, dwGlyphSetNameOffset)); pGlyphSetEntry[j].dwDataSize = pgsd->dwSize; pGlyphSetEntry[j].dwDataOffset = dwOffset; pGlyphSetEntry[j].dwGlyphSetType = 0; pGlyphSetEntry[j].dwFlags = 0; pGlyphSetEntry[j].dwReserved[0] = 0; pGlyphSetEntry[j].dwReserved[1] = 0;
dwOffset += pgsd->dwSize; j++; } }
// Fill in font metrics entries.
qsort(pNTM, dwFontMtxCount, sizeof(PNTM), compareFontMtx);
pFontMtxEntry = MemAllocZ(ulFontMtxEntrySize); if (!pFontMtxEntry) { ERR(("WriteNTF:MemAllocZ\n")); MemFree(pGlyphSetEntry); return(FALSE); }
if (dwOffset != (fileHeader.dwFontMtxOffset + ulFontMtxEntrySize + dwGlyphSetTotalSize2)) { ERR(("WriteNTF:dwOffset\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); return(FALSE); } for (i = 0; i < dwFontMtxCount; i++) { pFontMtxEntry[i].dwFontNameOffset = dwOffset + pNTM[i]->dwFontNameOffset; pFontMtxEntry[i].dwHashValue = HashKeyword(MK_PTR(pNTM[i], dwFontNameOffset)); pFontMtxEntry[i].dwDataSize = pNTM[i]->dwSize; pFontMtxEntry[i].dwDataOffset = dwOffset; pFontMtxEntry[i].dwVersion = 0; pFontMtxEntry[i].dwReserved[0] = 0; pFontMtxEntry[i].dwReserved[1] = 0; pFontMtxEntry[i].dwReserved[2] = 0;
dwOffset += pNTM[i]->dwSize; }
//
// Begin to write everything into the NTF file!
//
hNTFFile = CreateFile(pwszNTFFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hNTFFile == INVALID_HANDLE_VALUE) { ERR(("WriteNTF:CreateFile\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); return(FALSE); }
if (!WriteFile(hNTFFile, (LPVOID)&fileHeader, sizeof(NTF_FILEHEADER), (LPDWORD)&ulByteWritten, (LPOVERLAPPED)NULL) || (ulByteWritten != sizeof(NTF_FILEHEADER))) { ERR(("WriteNTF:WriteFile\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return(FALSE); } if (bVerbose) { char s[5]; s[0] = (char)(fileHeader.dwSignature >> 24); s[1] = (char)(fileHeader.dwSignature >> 16); s[2] = (char)(fileHeader.dwSignature >> 8); s[3] = (char)(fileHeader.dwSignature ); s[4] = '\0'; printf("NTF_FILEHEADER:dwSignature:%08X('%s')\n", fileHeader.dwSignature, s); s[0] = (char)(fileHeader.dwDriverType >> 24); s[1] = (char)(fileHeader.dwDriverType >> 16); s[2] = (char)(fileHeader.dwDriverType >> 8); s[3] = (char)(fileHeader.dwDriverType ); s[4] = '\0'; printf("NTF_FILEHEADER:dwDriverType:%08X('%s')\n", fileHeader.dwDriverType, s); printf("NTF_FILEHEADER:dwVersion:%08X\n", fileHeader.dwVersion); printf("NTF_FILEHEADER:dwGlyphSetCount:%ld\n", fileHeader.dwGlyphSetCount); printf("NTF_FILEHEADER:dwFontMtxCount:%ld\n", fileHeader.dwFontMtxCount); printf("\n"); }
if (!WriteFile(hNTFFile, (LPVOID)pGlyphSetEntry, ulGlyphSetEntrySize, (LPDWORD)&ulByteWritten, (LPOVERLAPPED)NULL) || (ulByteWritten != ulGlyphSetEntrySize)) { ERR(("WriteNTF:WriteFile\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return(FALSE); } if (bVerbose) { for (i = 0; i < dwGlyphSetCount2; i++) { printf("NTF_GLYPHSETENTRY for GLYPHSETDATA #%d\n", i + 1); printf("NTF_GLYPHSETENTRY:dwHashValue:%08X\n", pGlyphSetEntry[i].dwHashValue); printf("NTF_GLYPHSETENTRY:dwDataSize:%ld\n", pGlyphSetEntry[i].dwDataSize); printf("\n"); } }
if (!WriteFile(hNTFFile, (LPVOID)pFontMtxEntry, ulFontMtxEntrySize, (LPDWORD)&ulByteWritten, (LPOVERLAPPED)NULL) || (ulByteWritten != ulFontMtxEntrySize)) { ERR(("WriteNTF:WriteFile\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return(FALSE); } if (bVerbose) { for (i = 0; i < dwFontMtxCount; i++) { printf("NTF_FONTMTXENTRY for NTM #%d\n", i + 1); printf("NTF_FONTMTXENTRY:dwHashValue:%08X\n", pFontMtxEntry[i].dwHashValue); printf("NTF_FONTMTXENTRY:dwDataSize:%ld\n", pFontMtxEntry[i].dwDataSize); printf("NTF_FONTMTXENTRY:dwVersion:%08X\n", pFontMtxEntry[i].dwVersion); printf("\n"); } }
for (i = j = 0; i < dwGlyphSetCount; i++) { pgsd = pGlyphSetData[i];
// If no refernce mark is set with optimization option, ignore this
// glyphset data.
if (bOptimize && !(pgsd->dwReserved[0])) { pgsd = NULL; }
if (pgsd) { LONG lBytes, lSize = pgsd->dwSize; PBYTE pTemp = (PBYTE)pgsd;
pgsd->dwReserved[0] = 0; // Make sure it's cleared always.
while (lSize > 0) { lBytes = (lSize > 20000) ? 20000 : lSize; if (!WriteFile(hNTFFile, (LPVOID)pTemp, lBytes, (LPDWORD)&ulByteWritten, (LPOVERLAPPED)NULL) || (ulByteWritten != (ULONG)lBytes)) { ERR(("WriteNTF:WriteFile\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return(FALSE); } lSize -= 20000; pTemp += 20000; } }
if (bVerbose && pgsd) { printf("GLYPHSETDATA #%d\n", j++ + 1); printf("GLYPHSETDATA:dwSize:%ld\n", pgsd->dwSize); printf("GLYPHSETDATA:dwVersion:%08X\n", pgsd->dwVersion); printf("GLYPHSETDATA:dwFlags:%08X\n", pgsd->dwFlags); printf("GLYPHSETDATA:dwGlyphSetNameOffset:%s\n", (PSZ)MK_PTR(pgsd, dwGlyphSetNameOffset)); printf("GLYPHSETDATA:dwGlyphCount:%ld\n", pgsd->dwGlyphCount); printf("GLYPHSETDATA:dwRunCount:%ld\n", pgsd->dwRunCount); printf("GLYPHSETDATA:dwCodePageCount:%ld\n", pgsd->dwCodePageCount); printf("\n"); } }
for (i = 0; i < dwFontMtxCount; i++) { if (!WriteFile(hNTFFile, (LPVOID)pNTM[i], pNTM[i]->dwSize, (LPDWORD)&ulByteWritten, (LPOVERLAPPED)NULL) || (ulByteWritten != pNTM[i]->dwSize)) { ERR(("WriteNTF:WriteFile\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return(FALSE); }
if (bVerbose) { printf("NTM #%d\n", i + 1); printf("NTM:dwSize:%ld\n", pNTM[i]->dwSize); printf("NTM:dwVersion:%08X\n", pNTM[i]->dwVersion); printf("NTM:dwFlags:%08X\n", pNTM[i]->dwFlags); printf("NTM:dwFontNameOffset:%s\n", (PSZ)MK_PTR(pNTM[i], dwFontNameOffset)); printf("NTM:dwDisplayNameOffset:%S\n", (PTSTR)MK_PTR(pNTM[i], dwDisplayNameOffset)); printf("NTM:dwFontVersion:%08X\n", pNTM[i]->dwFontVersion); printf("NTM:dwGlyphSetNameOffset:%s\n", (PSZ)MK_PTR(pNTM[i], dwGlyphSetNameOffset)); printf("NTM:dwGlyphCount:%ld\n", pNTM[i]->dwGlyphCount); printf("NTM:dwCharWidthCount:%ld\n", pNTM[i]->dwCharWidthCount); printf("NTM:dwDefaultCharWidth:%ld\n", pNTM[i]->dwDefaultCharWidth); printf("NTM:dwKernPairCount:%ld\n", pNTM[i]->dwKernPairCount); printf("NTM:dwCharSet:%ld\n", pNTM[i]->dwCharSet); printf("NTM:dwCodePage:%ld\n", pNTM[i]->dwCodePage); printf("\n"); } }
//
// Write EOF marker
//
if (!WriteFile(hNTFFile, (LPVOID)&dwEofMark, sizeof (DWORD), (LPDWORD)&ulByteWritten, (LPOVERLAPPED)NULL) || (ulByteWritten != sizeof (DWORD))) { ERR(("WriteNTF:WriteFile:EOF\n")); MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return (FALSE); }
MemFree(pGlyphSetEntry); MemFree(pFontMtxEntry); CloseHandle(hNTFFile); return(TRUE); }
|