/*++ Copyright (c) 1996-1997 Microsoft Corporation Module Name: mkgttufm.c Abstract: Create CTT and PFM assignment table Environment: Windows NT PostScript driver Revision History: 01/17/97 -eigos- Created it. --*/ #include "precomp.h" // // Macros // #define FILENAME_SIZE 256 #define OUTPUT_VERBOSE 0x01 #define OUTPUT_ALL_MODELS 0x02 #define OUTPUT_CREATE_BATCH 0x04 #define RCFILE_FONTFILES 0 #define RCFILE_CTTFILES 1 #define RCFILE_GPCFILE 2 #define RCFILE_STRINGTABLE 3 #define WRITEDATATOFILE(pData) \ if (!WriteFile(hOutFile, \ (pData), \ (strlen(pData)), \ &dwWrittenSize, \ NULL)) \ { \ fprintf(stderr, gcstrWriteFileError ); \ ERR(("WriteFile")); \ } // // Error messages // #define ERROR_INVALID_ARGUMENT -1 #define ERROR_OPENFILE -2 #define ERROR_HEAP_CREATE -3 #define ERROR_RC_PARSING -4 #define ERROR_HEAP_ALLOC -5 #define ERROR_MODEL_DATA -6 #define ERROR_CREATE_RES_FONT_LIST -7 #define ERROR_CREATE_CART_FONT_LIST -8 #define ERROR_WRITEFILE -9 #define ARGUMENT_ERR_MSG_LINE 6 static BYTE *gcstrArgumentError[ARGUMENT_ERR_MSG_LINE] = { "Usage: mkgttufm [-vac] [Model Name ID] [Batch file name]\n", " -v Verbose\n", " -a Create all Model's data.\n", " [ModelName ID] is not necessary.\n", " -c Create font resource conversion batch file.\n", " [Batch file name] is necessary\n"}; static BYTE gcstrOpenFileFailure[] = "Cannot open file \"%ws\".\n"; static BYTE gcstrHeapCreateFailure[] = "Failed to Create Heap.\a"; static BYTE gcstrRCParsing[] = "Failed to process RC file.\n"; static BYTE gcstrHeapAlloc[] = "Failed to allocate memory.\n"; static BYTE gcstrModelData[] = "Model data is corrupted.\n"; static BYTE gcstrCreateResFontList[] = "Model:%d creation: BCreateResFontList failed.\n"; static BYTE gcstrCreateCartFontList[]= "Model:%d creation: BCreateCartFontList failed.\n"; static BYTE gcstrWriteFileError[] = "WriteFile failed\n"; // // Globals // DWORD gdwOutputFlags; static SHORT gResWordLen[4] = { 7, // RCFILE_FONTFILES = 0 11, // RCFILE_CTTFILES = 1 9, // RCFILE_GPCFILE = 2 11 }; // RCFILE_STRINGTABLE = 3 // // data structure that returns to the caller of library. // typedef struct tagPFM_ID_LIST { SHORT sFontID; // Font ID SHORT sCTTID; // CTT ID } PFM_ID_LIST, *PPFM_ID_LIST; typedef struct tagMODEL_FONTLIST { SHORT sID; // Model data ID SHORT sStringID; // Model string ID SHORT sDefaultCTT; // Default CTT ID DWORD dwNumOfResFont; PSHORT psResFontList; // Pointer from the top of this structure to font list DWORD dwNumOfCart; // Number of cont cartridge DWORD dwCartList; // Pointer from the top of this structure to cartridge // list } MODEL_FONTLIST, *PMODEL_FONTLIST; typedef struct tagCART_FONTLIST { SHORT sID; // Cartridge ID SHORT sStringID; // Cartridge string ID DWORD dwNumCartFont; DWORD dwFontList; // Offset from the top of this structure to font list } CART_FONTLIST, *PCART_FONTLIST; // // Internal use only // typedef struct tagFILE_NAME{ WORD wNext; SHORT sID; WCHAR wchFileName[1]; } FILE_NAME, *PFILE_NAME; // // Internal function prototype // BOOL BArgCheck( IN INT, IN CHAR **, OUT PDWORD, OUT PWSTR, OUT PWSTR); BOOL BProcessRCFile( IN HANDLE, IN PBYTE, IN PWSTR, IN DWORD, IN PDWORD, OUT PFILE_NAME*, IN PDWORD, OUT PFILE_NAME*); BOOL BCreateResFontList( IN HANDLE, IN PDH, IN PMODELDATA, IN DWORD, IN DWORD, OUT PSHORT, IN PSHORT); BOOL BCreateCartFontList( IN HANDLE, IN PDH, IN PMODELDATA, IN DWORD, IN PDWORD, IN PCART_FONTLIST, OUT PCART_FONTLIST*); PBYTE PGetNextToken( IN PSTR, OUT PSHORT); PBYTE PGetNextResWord( IN PSTR, OUT PSHORT); DWORD DwMergeFonts( IN DWORD, IN PSHORT, IN PSHORT, OUT PSHORT); SHORT SGetCTTID( IN DWORD, IN SHORT, IN PPFM_ID_LIST); SHORT SCountFontNum( IN PDH, IN WORD, IN WORD); SHORT SAdditionalFont( IN SHORT, IN PSHORT); VOID VPrintFontList( IN PMODEL_FONTLIST, IN DWORD, IN PPFM_ID_LIST); VOID VCreateBatchFile( IN PMODEL_FONTLIST, IN DWORD, IN PPFM_ID_LIST, IN PFILE_NAME, IN DWORD, IN PFILE_NAME, IN HANDLE); PCWSTR PcwstrGetFileName( SHORT, PFILE_NAME, DWORD); DWORD DwCTTID2CodePage( SHORT sCTTID); // // // Functions // // int __cdecl main( IN int argc, IN char **argv) /*++ Routine Description: main Arguments: argc - Number of parameters in the following argv - The parameters, starting with our name Return Value: Return error code Note: --*/ { PFILE_NAME pPFMFileNameListSrc, pPFMFileNameList; PFILE_NAME pCTTFileNameListSrc, pCTTFileNameList; PFILE_NAME pStringIDListSrc, pStringIDList; PPFM_ID_LIST pPFM_ID, pPFM_ID_Src; PMODEL_FONTLIST pModelFontList, pModelFontListSrc; MODEL_FONTLIST ModelFontList; PCART_FONTLIST pCartFontList, pCartFontListSrc; PCART_FONTLIST pCartList; PDH pGPCData; PMODELDATA pModelData; PGPCFONTCART pFontCart; FONTIN FontIn; EXTTEXTMETRIC Etm; HFILEMAP hRCFile, hPFMFile, hGPCFile; HANDLE hHeap, hOutFile; DWORD dwRCFileSize, dwGPCFileSize, dwPFMFileSize; DWORD dwTotalNumOfPFM, dwTotalNumOfCTT; DWORD dwFontCartTotalSize; DWORD dwModelID; DWORD dwOffset; DWORD dwNFonts; DWORD dwI; PSHORT psTempList1, psTempList2; SHORT sModelDataSize; SHORT sModelDataCount; SHORT sNumOfFontCart; SHORT sFontCartSize; SHORT sOrientOffset; SHORT sI, sJ; WCHAR awchRCFile[FILENAME_SIZE]; WCHAR awchGPCFile[FILENAME_SIZE]; WCHAR awchOutFile[FILENAME_SIZE]; PBYTE pRCFile; PBYTE pPFM; BOOL bFlipFlop; dwModelID = 0; // // Argument check // mkgttufm [-va] [Model Name ID] // -v Verbose // -a Create all Model's data. In this case ModelName is not necessary. // if (!BArgCheck(argc, argv, &dwModelID, awchRCFile, awchOutFile)) { for (sI = 0; sI < ARGUMENT_ERR_MSG_LINE; sI++) { fprintf( stderr, gcstrArgumentError[sI]); } return ERROR_INVALID_ARGUMENT; } // // Open *.RC file. // if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("***********************************************************\n"); printf("FILE: %ws\n", awchRCFile); printf("***********************************************************\n"); } if (!(hRCFile = MapFileIntoMemory( (PTSTR)awchRCFile, (PVOID)&pRCFile, (PDWORD)&dwRCFileSize ))) { fprintf( stderr, gcstrOpenFileFailure, awchRCFile); return ERROR_OPENFILE; } // // Heap Creation // if (!(hHeap = HeapCreate( HEAP_NO_SERIALIZE, 0x10000, 0x10000))) { fprintf( stderr, gcstrHeapCreateFailure); ERR(("CreateHeap failed: %d\n", GetLastError())); return ERROR_HEAP_CREATE; } // // Parse RC file and get GPC file name, PFM file name and CTT file name // if (!BProcessRCFile(hHeap, pRCFile, awchGPCFile, FILENAME_SIZE, &dwTotalNumOfPFM, &pPFMFileNameListSrc, &dwTotalNumOfCTT, &pCTTFileNameListSrc)) { HeapDestroy(hHeap); fprintf(stderr, gcstrRCParsing); return ERROR_RC_PARSING; } if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("***********************************************************\n"); printf("All CTT data in this minidriver\n"); printf("***********************************************************\n"); pCTTFileNameList = pCTTFileNameListSrc; for (dwI = 0; dwI < dwTotalNumOfCTT; dwI ++) { printf("CTT[%3d], File=%ws\n", pCTTFileNameList->sID, pCTTFileNameList->wchFileName); (PBYTE)pCTTFileNameList += pCTTFileNameList->wNext; } } // // Open all PFM files and get CTT ID // if (!(pPFM_ID_Src = HeapAlloc(hHeap, 0, dwTotalNumOfPFM * sizeof(PFM_ID_LIST)))) { HeapDestroy(hHeap); fprintf(stderr, gcstrHeapAlloc); ERR(("HeapAlloc failed: %d\n", GetLastError())); return ERROR_HEAP_ALLOC; } pPFM_ID = pPFM_ID_Src; pPFMFileNameList = pPFMFileNameListSrc; if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("***********************************************************\n"); printf("All fonts in this minidriver\n"); printf("***********************************************************\n"); } for (dwI = 0; dwI < dwTotalNumOfPFM; dwI ++) { if (!(hPFMFile = MapFileIntoMemory( (PTSTR)pPFMFileNameList->wchFileName, (PVOID)&pPFM, (PDWORD)&dwPFMFileSize))) { fprintf(stderr, gcstrOpenFileFailure, (PTSTR)pPFMFileNameList->wchFileName); HeapDestroy(hHeap); return ERROR_OPENFILE; } FontIn.pETM = &Etm; FontIn.pBase = pPFM; BAlignPFM(&FontIn); // // Fill out PFM_ID // pPFM_ID->sFontID = pPFMFileNameList->sID; pPFM_ID->sCTTID = FontIn.DI.sTransTab; if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("Font[%3d]:sCTTID=%2d, File=%ws\n", pPFM_ID->sFontID, pPFM_ID->sCTTID, pPFMFileNameList->wchFileName); } pPFM_ID++; UnmapFileFromMemory(hPFMFile); (PBYTE)pPFMFileNameList += pPFMFileNameList->wNext; } // // Open GPC file // if (!(hGPCFile = MapFileIntoMemory((PTSTR)awchGPCFile, (PVOID)&pGPCData, &dwGPCFileSize))) { fprintf( stderr, gcstrOpenFileFailure, awchGPCFile); return ERROR_OPENFILE; } // // Get Model data // sModelDataCount = pGPCData->rghe[HE_MODELDATA].sCount; sModelDataSize = pGPCData->rghe[HE_MODELDATA].sLength; pModelData = (PMODELDATA)((PBYTE)pGPCData + pGPCData->rghe[HE_MODELDATA].sOffset); if (dwModelID > (DWORD)sModelDataCount) { HeapDestroy(hHeap); fprintf(stderr, gcstrModelData); return ERROR_MODEL_DATA; } // // Get Font cartridge information // sNumOfFontCart = pGPCData->rghe[HE_FONTCART].sCount; sFontCartSize = pGPCData->rghe[HE_FONTCART].sLength; pFontCart = (PGPCFONTCART)((PBYTE)pGPCData + pGPCData->rghe[HE_FONTCART].sOffset); // // Count memory size // dwFontCartTotalSize = (DWORD)sNumOfFontCart * sizeof(CART_FONTLIST); for (sI = 0; sI < sNumOfFontCart; sI ++) { dwFontCartTotalSize += (SCountFontNum(pGPCData, pFontCart->orgwPFM[FC_ORGW_PORT], pFontCart->orgwPFM[FC_ORGW_LAND]) + 1) * sizeof(SHORT); (PBYTE)pFontCart += sFontCartSize; } pCartFontListSrc = pCartFontList = HeapAlloc(hHeap, 0, dwFontCartTotalSize); if (!pCartFontList) { HeapDestroy(hHeap); fprintf(stderr, gcstrHeapAlloc); ERR(("HeapAlloc failed: %d\n", GetLastError())); return ERROR_HEAP_ALLOC; } pFontCart = (PGPCFONTCART)((PBYTE)pGPCData + pGPCData->rghe[HE_FONTCART].sOffset); dwOffset = sNumOfFontCart * sizeof(CART_FONTLIST); psTempList1 = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 2 * sizeof(SHORT) * dwTotalNumOfPFM); if (!psTempList1) { ERR(("HeapAlloc failed: %d\n", GetLastError())); return FALSE; } psTempList2 = psTempList1 + dwTotalNumOfPFM; if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("***********************************************************\n"); printf("Font Cartridge info\n"); printf("Number of Font Cartridge = %d\n", sNumOfFontCart); } for (sI = 1; sI <= sNumOfFontCart; sI ++) { if (pModelData->fGeneral & MD_ROTATE_FONT_ABLE) { sOrientOffset = 1; bFlipFlop = TRUE; } else { sOrientOffset = 0; bFlipFlop = FALSE; } *psTempList1 = *psTempList2 = 0; pCartFontList->sID = sI; pCartFontList->sStringID = pFontCart->sCartNameID; pCartFontList->dwFontList = dwOffset; if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("***********************************************************\n"); printf("Font cartridge ID = %d\n", sI); printf("Font cartridge string ID = %d\n", pFontCart->sCartNameID); } for (sJ = 0; sJ <= sOrientOffset; sJ++) { dwNFonts = DwMergeFonts(dwTotalNumOfPFM, bFlipFlop ? psTempList1 : psTempList2, (PSHORT) ((PBYTE)pGPCData + pGPCData->loHeap + pFontCart->orgwPFM[FC_ORGW_PORT + sJ]), bFlipFlop ? psTempList2 : psTempList1); bFlipFlop = !bFlipFlop; if (dwNFonts == dwTotalNumOfPFM) { break; } } if (gdwOutputFlags & OUTPUT_VERBOSE) { printf("Number of font = %d\n", dwNFonts); printf("-----------------------------------------------------------\n"); for (dwI = 0; dwI < dwNFonts; dwI ++) { printf("FontID[%2d] = %d\n", dwI + 1, psTempList1[dwI]); } } pCartFontList->dwNumCartFont = dwNFonts; CopyMemory((PBYTE)pCartFontList + dwOffset, psTempList1, (dwNFonts + 1) * sizeof(SHORT)); dwOffset += sizeof(SHORT) * (dwNFonts + 1) - sizeof(CART_FONTLIST); (PBYTE)pFontCart += sFontCartSize; pCartFontList ++; } // // Get CTT ID // if (!(gdwOutputFlags & OUTPUT_ALL_MODELS)) { (PBYTE)pModelData += sModelDataSize * dwModelID; pModelFontListSrc = pModelFontList = &ModelFontList; pModelFontList->sID = (SHORT)dwModelID; pModelFontList->sStringID = pModelData->sIDS; pModelFontList->sDefaultCTT = pModelData->sDefaultCTT; pModelFontList->dwNumOfResFont = SCountFontNum(pGPCData, pModelData->rgoi[MD_OI_PORT_FONTS], pModelData->rgoi[MD_OI_LAND_FONTS]); pModelFontList->psResFontList = HeapAlloc( hHeap, HEAP_ZERO_MEMORY, (pModelFontList->dwNumOfResFont + 1) * sizeof(SHORT)); if (pModelFontList->psResFontList == NULL) { HeapDestroy(hHeap); fprintf(stderr, gcstrHeapAlloc); ERR(("HeapAlloc failed: %d\n", GetLastError())); return FALSE; } if (!BCreateResFontList(hHeap, pGPCData, pModelData, dwTotalNumOfPFM, pModelFontList->dwNumOfResFont, pModelFontList->psResFontList, psTempList1)) { HeapDestroy(hHeap); fprintf(stderr, gcstrCreateResFontList, dwModelID); return ERROR_CREATE_RES_FONT_LIST; } if (!BCreateCartFontList(hHeap, pGPCData, pModelData, dwTotalNumOfPFM, &(pModelFontList->dwNumOfCart), pCartFontListSrc, (PCART_FONTLIST*)&(pModelFontList->dwCartList))) { HeapDestroy(hHeap); fprintf(stderr, gcstrCreateCartFontList, dwModelID); return ERROR_CREATE_CART_FONT_LIST; } } else { pModelFontListSrc = pModelFontList = HeapAlloc(hHeap, 0, sModelDataCount * sizeof(MODEL_FONTLIST)); dwOffset = sModelDataCount * sizeof(MODEL_FONTLIST); for (sI = 0; sI < sModelDataCount; sI ++, pModelFontList++) { pModelFontList->sID = sI; pModelFontList->sStringID = pModelData->sIDS; pModelFontList->sDefaultCTT = pModelData->sDefaultCTT; pModelFontList->dwNumOfResFont = SCountFontNum(pGPCData, pModelData->rgoi[MD_OI_PORT_FONTS], pModelData->rgoi[MD_OI_LAND_FONTS]); pModelFontList->psResFontList = HeapAlloc( hHeap, HEAP_ZERO_MEMORY, (pModelFontList->dwNumOfResFont + 1) * sizeof(SHORT)); if (pModelFontList->psResFontList == NULL) { HeapDestroy(hHeap); fprintf(stderr, gcstrHeapAlloc); ERR(("HeapAlloc failed: %d\n", GetLastError())); return FALSE; } if (!BCreateResFontList(hHeap, pGPCData, pModelData, dwTotalNumOfPFM, pModelFontList->dwNumOfResFont, pModelFontList->psResFontList, psTempList1)) { HeapDestroy(hHeap); fprintf(stderr, gcstrCreateResFontList, sI); return ERROR_CREATE_RES_FONT_LIST; } if (!BCreateCartFontList( hHeap, pGPCData, pModelData, dwTotalNumOfPFM, &(pModelFontList->dwNumOfCart), pCartFontListSrc, (PCART_FONTLIST*)&(pModelFontList->dwCartList))) { HeapDestroy(hHeap); fprintf(stderr, gcstrCreateCartFontList, sI); return ERROR_CREATE_CART_FONT_LIST; } dwOffset += pModelFontList->dwNumOfResFont * sizeof(SHORT); (PBYTE)pModelData += sModelDataSize; } } UnmapFileFromMemory(hGPCFile); if (!(gdwOutputFlags & OUTPUT_ALL_MODELS)) { VPrintFontList(pModelFontListSrc, dwTotalNumOfPFM, pPFM_ID_Src); if (gdwOutputFlags & OUTPUT_CREATE_BATCH) { hOutFile = CreateFile(awchOutFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); VCreateBatchFile(pModelFontListSrc, dwTotalNumOfPFM, pPFM_ID_Src, pPFMFileNameListSrc, dwTotalNumOfCTT, pCTTFileNameListSrc, hOutFile); CloseHandle(hOutFile); } } else { pModelFontList = pModelFontListSrc; if (gdwOutputFlags & OUTPUT_CREATE_BATCH) { hOutFile = CreateFile(awchOutFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); } for (sI = 0; sI < sModelDataCount; sI ++, pModelFontList++) { VPrintFontList(pModelFontListSrc, dwTotalNumOfPFM, pPFM_ID_Src); if (gdwOutputFlags & OUTPUT_CREATE_BATCH) { VCreateBatchFile(pModelFontList, dwTotalNumOfPFM, pPFM_ID_Src, pPFMFileNameListSrc, dwTotalNumOfCTT, pCTTFileNameListSrc, hOutFile); } } if (gdwOutputFlags & OUTPUT_CREATE_BATCH) { CloseHandle(hOutFile); } } HeapDestroy(hHeap); return 0; } // // // Helper functions. // // BOOL BProcessRCFile( IN HANDLE hHeap, IN PBYTE pCurrent, IN PWSTR pwstrGPCFileName, IN DWORD dwcwGPCFileName, IN PDWORD pdwTotalNumOfPFM, OUT PFILE_NAME *ppPFMFileName, IN PDWORD pdwTotalNumOfCTT, OUT PFILE_NAME *ppCTTFileName) { PFILE_NAME pPFMFileNameListSrc, pPFMFileNameList; PFILE_NAME pCTTFileNameListSrc, pCTTFileNameList; DWORD dwPFMListSize, dwCTTListSize; DWORD dwcwWrittenSize, dwRestOfBuffer; SHORT sResType; SHORT sLen, sID; CHAR strID[8]; CHAR strFileName[32]; PBYTE pTemp; if (!pCurrent) { return FALSE; } // // Initial size // *pdwTotalNumOfPFM = 0; *pdwTotalNumOfCTT = 0; dwPFMListSize = 400 * (sizeof(FILE_NAME) + 32 * sizeof(WCHAR)); pPFMFileNameListSrc = pPFMFileNameList = (PFILE_NAME)HeapAlloc(hHeap, 0, dwPFMListSize); dwCTTListSize = 10 * (sizeof(FILE_NAME) + 32 * sizeof(WCHAR)); pCTTFileNameListSrc = pCTTFileNameList = (PFILE_NAME)HeapAlloc(hHeap, 0, dwCTTListSize); while (pCurrent = PGetNextResWord(pCurrent, &sResType)) { if (sResType == RCFILE_STRINGTABLE) { // // skip "STRINGTABLE" // pCurrent = pCurrent + gResWordLen[sResType]; while (pCurrent = PGetNextToken(pCurrent, (PSHORT)&sLen)) { if (sLen == 5 && !strncmp(pCurrent, "BEGIN", sLen)) { break; } else { pCurrent += sLen; } } if (!pCurrent) { return FALSE; } // // skip over "BEGIN" // pCurrent += sLen; // // process until reaching "END" // while (pCurrent = PGetNextToken(pCurrent, (PSHORT)&sLen)) { if (sLen == 3 && !strncmp(pCurrent, "END", sLen)) { break; } else { pCurrent += sLen; } } if (!pCurrent) { return FALSE; } // // skip over "END", which // is the only way we can // be here... // pCurrent += 3; } else { // // We have a file name... // // // remember the position past the reserved word. // pTemp = pCurrent + gResWordLen[sResType]; // // move back to the last token. // pCurrent -= 1; while (isspace(*pCurrent)) { pCurrent--; } // // move to the head of the token before the reserved word // We expect an id # before RC_TABLES, RC_FONT or RC_TRANSTAB. // First, initialize the sLength count of the id. // sLen = 0; while (!isspace(*pCurrent)) { pCurrent--; sLen++; } pCurrent++; // // convert the id // ZeroMemory(strID, sizeof(strID)); strncpy(strID, pCurrent, sLen); if (!(sID = atoi(strID))) { return FALSE; } // // Extract the associated file name. // But first, skip load and memory options. // while (pTemp = PGetNextToken(pTemp, (PSHORT)&sLen)) { if ((sLen == 10 && !strncmp(pTemp, "LOADONCALL", sLen)) || (sLen == 7 && !strncmp(pTemp, "PRELOAD", sLen)) || (sLen == 8 && !strncmp(pTemp, "MOVEABLE", sLen)) || (sLen == 11 && !strncmp(pTemp, "DISCARDABLE", sLen)) || (sLen == 5 && !strncmp(pTemp, "FIXED", sLen)) ) { // continue skipping pTemp += sLen; } else { break; } } if (!pTemp) { return FALSE; } // // 'pTemp' points to the file // name. Copy to strFileName // memset(strFileName, 0, sizeof(strFileName)); strncpy(strFileName, pTemp, sLen); strFileName[sLen] = 0; switch (sResType) { case RCFILE_GPCFILE: if (!(dwcwWrittenSize = MultiByteToWideChar(CP_ACP, 0, strFileName, sLen, pwstrGPCFileName, dwcwGPCFileName))) { ERR(("MultiByteToWideChar failed: %d\n", GetLastError())); VERBOSE(("String : %s\n", strFileName)); return FALSE; } pwstrGPCFileName[dwcwWrittenSize] = (WCHAR)NULL; break; case RCFILE_FONTFILES: dwRestOfBuffer = pPFMFileNameList - pPFMFileNameListSrc; dwRestOfBuffer = dwPFMListSize - dwRestOfBuffer; if (dwRestOfBuffer < 32 * sizeof(WCHAR)) { dwPFMListSize += 50 * (sizeof(DWORD) + 32 * sizeof(WCHAR)); HeapReAlloc(hHeap, 0, pPFMFileNameListSrc, dwPFMListSize); } if (!(dwcwWrittenSize = MultiByteToWideChar( CP_ACP, 0, strFileName, sLen, pPFMFileNameList->wchFileName, dwRestOfBuffer))) { ERR(("MultiByteToWideChar failed: %d\n", GetLastError())); VERBOSE(("String : %s\n", strFileName)); return FALSE; } pPFMFileNameList->wchFileName[dwcwWrittenSize++] = (WCHAR)NULL; pPFMFileNameList->sID = sID; pPFMFileNameList->wNext = sizeof(FILE_NAME) + dwcwWrittenSize * sizeof(WCHAR); (PBYTE)pPFMFileNameList += pPFMFileNameList->wNext; (*pdwTotalNumOfPFM)++; break; case RCFILE_CTTFILES: dwRestOfBuffer = pCTTFileNameList - pCTTFileNameListSrc; dwRestOfBuffer = dwCTTListSize - dwRestOfBuffer; if (dwRestOfBuffer < 32 * sizeof(WCHAR)) { dwCTTListSize += 50 * (sizeof(DWORD) + 32 * sizeof(WCHAR)); HeapReAlloc(hHeap, 0, pCTTFileNameListSrc, dwCTTListSize); } if (!(dwcwWrittenSize = MultiByteToWideChar( CP_ACP, 0, strFileName, sLen, pCTTFileNameList->wchFileName, dwRestOfBuffer))) { ERR(("MultiByteToWideChar failed: %d\n", GetLastError())); VERBOSE(("String : %s\n", strFileName)); return FALSE; } pCTTFileNameList->wchFileName[dwcwWrittenSize++] = (WCHAR)NULL; pCTTFileNameList->sID = sID; pCTTFileNameList->wNext = sizeof(FILE_NAME) + dwcwWrittenSize * sizeof(WCHAR); (PBYTE)pCTTFileNameList += pCTTFileNameList->wNext; (*pdwTotalNumOfCTT)++; break; break; } // // move the current buffer // pointer over the file name. // pCurrent = pTemp + sLen; } // // move pointers forward. // Skip space characters // while (isspace(*pCurrent)) { pCurrent++; } } /* while */ *ppPFMFileName = pPFMFileNameListSrc; *ppCTTFileName = pCTTFileNameListSrc; return TRUE; } PBYTE PGetNextToken( IN PSTR pBuf, OUT PSHORT psLen) /*++ Routine Description: Search for the next token in the buffer (null-terminated) and return the pointer to the first character in the token. Its Length is returned via pssLen. A token is a character string that is not inside a comment and does not contain any space characters (\x09, \x0A, \x0B, \x0C, \x0D and \x20). It can be at most 128 bytes long. Arguments: pBuf - far ptr to null term str buffer psLen - nera ptr to where to write strsLen of token to Return Value: ptr to first char in token --*/ { SHORT sI; while (*pBuf) { // // skip space characters // while (isspace(*pBuf)) { pBuf++; } // // get past comments // if (*pBuf == '/') { if (*(pBuf + 1) == '/') { // // single-line comment. Search until the end of the line. // It can be twice as fast if we write our own loops here. // pBuf = strstr(pBuf, "\x0D\x0A") + 2; continue; // back to start of while } else if (*(pBuf + 1) == '*') { // // multi-line comment. Search for "*/". // pBuf = strstr(pBuf, "*/") + 2; continue; // back to start of while } } // // this is the beginning of a token // for (sI = 0; !isspace(pBuf[sI]) && pBuf[sI]!=0; sI++); *psLen = sI; if (pBuf) { return pBuf; } } *psLen = 0; return NULL; } PBYTE PGetNextResWord( IN PSTR pBuf, OUT PSHORT psResType) /*++ Routine Description: Search for the next reserved word (RC_TABLES, RC_FONT, RC_TRANSTAB, or STRINGTABLE) in the buffer. Return the pointer to the first character in the reserved word. Its type is returned via a parameter. Note: strtok deliberately not used here since it inserts null terminators into the buffer. Note: This routine will assume PGetNextToken skips any reserved words that occur within a comment. Arguments: pBuf - psResType - Return Value: ptr to next reserved word, NULL if none found --*/ { SHORT sLen; while (pBuf = PGetNextToken(pBuf, (PSHORT)&sLen)) { if (sLen == gResWordLen[RCFILE_FONTFILES] && !strncmp(pBuf, "RC_FONT", sLen)) { *psResType = RCFILE_FONTFILES; return pBuf; } else if (sLen == gResWordLen[RCFILE_GPCFILE] && !strncmp(pBuf, "RC_TABLES", sLen)) { *psResType = RCFILE_GPCFILE; return pBuf; } else if (sLen == gResWordLen[RCFILE_CTTFILES] && !strncmp(pBuf, "RC_TRANSTAB", sLen)) { *psResType = RCFILE_CTTFILES; return pBuf; } else if (sLen == gResWordLen[RCFILE_STRINGTABLE] && !strncmp(pBuf, "STRINGTABLE", sLen)) { *psResType = RCFILE_STRINGTABLE; return pBuf; } else // continue searching. pBuf += sLen; } // while *psResType = -1; return NULL; } DWORD DwMergeFonts( IN DWORD dwTotalNumOfPFM, IN PSHORT pBase, // source 1 IN PSHORT pSrc, // source 2 OUT PSHORT pDest) // result buffer. Can hold max dwTotalNumOfPFM entries /*++ Routine Description: Merge two font id lists into one. Arguments: pBase - an ordered list of font id's to be merged. lpSrc - an ordered list of font id's, but the first two id's represent a range of contiguous font id's lpDest - a buffer for the result, which is a a list of font id's just like the base list. The max limit is dwTotalNumOfPFM (not including terminating 0). Return Value: the actual # of font id's in the result list. --*/ { SHORT i; // trace pBase list. SHORT j; // trace pSrc list; SHORT k; // trace destination buffer SHORT sID; k = 0; for (i = 0; pBase[i] != 0 && pBase[i] < pSrc[0] && k < (SHORT)dwTotalNumOfPFM; ) { pDest[k++] = pBase[i++]; } // // expand the range represented by pSrc[0]..pSrc[1] // if (pSrc[0] > 0) { for (sID = pSrc[0]; sID <= pSrc[1] && k < (SHORT)dwTotalNumOfPFM; sID++) { pDest[k++] = sID; } j = 2; // // skip repeated ones. // while (pBase[i] != 0 && pBase[i] <= pSrc[1]) { i++; } } else { // // pSrc[] list is empty. // j = 0; } // merge the rest of the lists while (pBase[i] != 0 && pSrc[j] != 0 && k < (SHORT)dwTotalNumOfPFM) { if (pBase[i] < pSrc[j]) pDest[k++] = pBase[i++]; else if (pBase[i] > pSrc[j]) pDest[k++] = pSrc[j++]; else { // pBase[i] == pSrc[j] case pDest[k++] = pBase[i++]; j++; } } if (pBase[i] == 0) { while (pSrc[j] != 0 && pSrc[j] <= (SHORT)dwTotalNumOfPFM && k < (SHORT)dwTotalNumOfPFM) { pDest[k++] = pSrc[j++]; } } if (pSrc[j] == 0) { while (pBase[i] != 0 && pBase[i] <= (SHORT)dwTotalNumOfPFM && k < (SHORT)dwTotalNumOfPFM) { pDest[k++] = pBase[i++]; } } // // terminate the result list by zero. // pDest[k] = 0; return k; } BOOL BCreateResFontList( IN HANDLE hHeap, IN PDH pGPCData, IN PMODELDATA pModelData, IN DWORD dwTotalNumOfPFM, IN DWORD dwNumOfFont, OUT PSHORT psList, IN PSHORT psTempBuffer) { DWORD dwNFonts; PSHORT psTempList1, psTempList2; SHORT sOrientOffset, sI; BOOL bFlipFlop; if (pModelData->fGeneral & MD_ROTATE_FONT_ABLE) { sOrientOffset = 1; bFlipFlop = TRUE; } else { sOrientOffset = 0; bFlipFlop = FALSE; } psTempList1 = psTempBuffer; psTempList2 = psTempList1 + 1 + dwNumOfFont; *psTempList1 = *psTempList2 = 0; // // look at resident (ROM) fonts. // for (sI = 0; sI <= sOrientOffset; sI++) { dwNFonts = DwMergeFonts(dwTotalNumOfPFM, bFlipFlop ? psTempList1 : psTempList2, (PSHORT) ((PBYTE)pGPCData + pGPCData->loHeap + pModelData->rgoi[MD_OI_PORT_FONTS + sI]), bFlipFlop ? psTempList2 : psTempList1); bFlipFlop = !bFlipFlop; if (dwNFonts == dwTotalNumOfPFM) { break; } } CopyMemory(psList, psTempList1, sizeof(SHORT) * (1 + dwNumOfFont)); return TRUE; } BOOL BCreateCartFontList( IN HANDLE hHeap, IN PDH pGPCData, IN PMODELDATA pModelData, IN DWORD dwTotalNumOfPFM, IN PDWORD pdwNumOfCart, IN PCART_FONTLIST pCartFontListSrc, OUT PCART_FONTLIST *ppCartFontList) { PCART_FONTLIST pCartSrc, pCart; DWORD dwNFonts, dwCartNumOfThisModel, dwTotalFontInAllCart; DWORD dwOffset, dwI; PSHORT psFontCart, psFontCartSrc; // // Get Cartridge number // psFontCartSrc = psFontCart = (PSHORT)((PBYTE)pGPCData + pGPCData->loHeap + pModelData->rgoi[MD_OI_FONTCART]); dwCartNumOfThisModel = 0; dwTotalFontInAllCart = 0; while(*psFontCart) { dwTotalFontInAllCart += pCartFontListSrc[*psFontCart-1].dwNumCartFont; psFontCart++; dwCartNumOfThisModel++; } if (dwCartNumOfThisModel == 0) { *ppCartFontList = NULL; *pdwNumOfCart = 0; return TRUE; } *pdwNumOfCart = dwCartNumOfThisModel; // // then, look at internal cartridge fonts. // pCart = pCartSrc = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwCartNumOfThisModel * sizeof(CART_FONTLIST) + dwTotalFontInAllCart * sizeof(SHORT) + dwCartNumOfThisModel * sizeof(SHORT)); if (!pCart) { ERR(("HeapAlloc failed: %d\n", GetLastError())); return FALSE; } psFontCart = psFontCartSrc; dwOffset = dwCartNumOfThisModel * sizeof(CART_FONTLIST); for (dwI = 0; dwI < dwCartNumOfThisModel; dwI++, psFontCart++) { pCart->sID = pCartFontListSrc[*psFontCart-1].sID; pCart->sStringID = pCartFontListSrc[*psFontCart-1].sStringID; pCart->dwNumCartFont = pCartFontListSrc[*psFontCart-1].dwNumCartFont; pCart->dwFontList = dwOffset; CopyMemory((PBYTE)pCart + pCart->dwFontList, (PBYTE)(pCartFontListSrc + *psFontCart - 1) + pCartFontListSrc[*psFontCart-1].dwFontList, (pCartFontListSrc[*psFontCart-1].dwNumCartFont + 1) * sizeof(SHORT)); dwOffset += sizeof(SHORT) * (pCartFontListSrc[*psFontCart-1].dwNumCartFont + 1) - sizeof(CART_FONTLIST); pCart++; } *ppCartFontList = pCartSrc; } BOOL BArgCheck( IN INT iArgc, IN CHAR **ppArgv, OUT PDWORD pdwModelID, OUT PWSTR pwstrRCFile, OUT PWSTR pwstrOutFile) { DWORD dwI; INT iParamType, iRet; ASSERT(pdwModelID != NULL || pwstrRCFile != NULL ); if (iArgc < 3 || iArgc > 5) { return FALSE; } ppArgv++; iArgc --; iParamType = 0; *pdwModelID = 0; gdwOutputFlags = 0; while (iArgc > 0) { if (**ppArgv == '-' || **ppArgv == '/') { dwI = 1; while(*(*ppArgv+dwI)) { switch(*(*ppArgv+dwI)) { case 'v': gdwOutputFlags |= OUTPUT_VERBOSE; break; case 'a': gdwOutputFlags |= OUTPUT_ALL_MODELS; iParamType = 1; break; case 'c': gdwOutputFlags |= OUTPUT_CREATE_BATCH; break; } dwI ++; } } else { if (iParamType == 0) { *pdwModelID = (DWORD)atoi(*ppArgv); } else if (iParamType == 1) { iRet = MultiByteToWideChar(CP_ACP, 0, *ppArgv, strlen(*ppArgv), pwstrRCFile, FILENAME_SIZE); *(pwstrRCFile + iRet) = (WCHAR)NULL; } if (iParamType == 2) { iRet = MultiByteToWideChar(CP_ACP, 0, *ppArgv, strlen(*ppArgv), pwstrOutFile, FILENAME_SIZE); *(pwstrOutFile + iRet) = (WCHAR)NULL; } iParamType ++; } iArgc --; ppArgv++; } return TRUE; } SHORT SGetCTTID( IN DWORD dwTotalNumOfPFM, IN SHORT sFontID, IN PPFM_ID_LIST pPFM_ID) { SHORT sI; for (sI = 0; sI < (SHORT)dwTotalNumOfPFM; sI ++, pPFM_ID++) { if(sFontID == pPFM_ID->sFontID) { return pPFM_ID->sCTTID; } } return (SHORT)0x8FFF; } VOID VPrintFontList( IN PMODEL_FONTLIST pModelFontList, IN DWORD dwTotalNumOfPFM, IN PPFM_ID_LIST pPFM_ID) { PCART_FONTLIST pCartFontList; DWORD dwI, dwJ; PSHORT psFontID; SHORT sCTTID; printf("***********************************************************\n"); printf("Model ID : %d\n", pModelFontList->sID); printf("Model Name String ID : %d\n", pModelFontList->sStringID); printf("Default CTT ID : %d\n", pModelFontList->sDefaultCTT); printf("Number of resident font : %d\n", pModelFontList->dwNumOfResFont); printf("Number of font cartridge: %d\n", pModelFontList->dwNumOfCart); printf("***********************************************************\n"); printf("Resident font list\n"); printf("***********************************************************\n"); psFontID = (PSHORT)(pModelFontList->psResFontList); for (dwI = 1; dwI <= pModelFontList->dwNumOfResFont; dwI++, psFontID++) { sCTTID = SGetCTTID(dwTotalNumOfPFM, *psFontID, pPFM_ID); if (sCTTID == (SHORT)0x8FFF) { printf("Invalid CTT ID\n"); } else { if (sCTTID == 0) { sCTTID = pModelFontList->sDefaultCTT; } printf("FontID[%3d]=%3d, CTTID=%3d\n", dwI, *psFontID, sCTTID); } } if (pModelFontList->dwNumOfCart) { printf("***********************************************************\n"); printf("Cartridge font list\n"); } pCartFontList = (PCART_FONTLIST)pModelFontList->dwCartList; for (dwI = 0; dwI < pModelFontList->dwNumOfCart; dwI ++, pCartFontList++) { printf("***********************************************************\n"); printf("CartridgeID = %d\n", pCartFontList->sID); printf("StringID = %d\n", pCartFontList->sStringID); printf("Number of fonts = %d\n", pCartFontList->dwNumCartFont); printf("-----------------------------------------------------------\n"); psFontID = (PSHORT)((PBYTE)pCartFontList + pCartFontList->dwFontList); for (dwJ = 0; dwJ < pCartFontList->dwNumCartFont; dwJ ++, psFontID++) { sCTTID = SGetCTTID(dwTotalNumOfPFM, *psFontID, pPFM_ID); if (sCTTID == (SHORT)0x8FFF) { printf("Invalid CTT ID\n"); } else { if (sCTTID == 0) { sCTTID = pModelFontList->sDefaultCTT; } printf("FontID[%3d]=%3d, CTTID=%3d\n", dwJ + 1, *psFontID, sCTTID); } } } } VOID VCreateBatchFile( IN PMODEL_FONTLIST pModelFontList, IN DWORD dwTotalNumOfPFM, IN PPFM_ID_LIST pPFM_ID, IN PFILE_NAME pPFM_FileNameSrc, IN DWORD dwTotalNumOfCTT, IN PFILE_NAME pCTT_FileNameSrc, IN HANDLE hOutFile) { PCART_FONTLIST pCartFontList; PFILE_NAME pPFM_FileName, pCTT_FileName; PCWSTR pcwstrPFMFileName, pcwstrCTTFileName; WCHAR wchFileName1[FILENAME_SIZE]; WCHAR wchFileName2[FILENAME_SIZE]; DWORD dwWrittenSize; DWORD dwI, dwJ, dwK; PSHORT psFontID; SHORT sCTTID; BYTE aubBuff[512]; DWORD dwPFM2UFMMode; DWORD dwCodePage; #define PFM2UFM_GTTMODE 0 #define PFM2UFM_CODEPAGE 1 #define PFM2UFM_DEF_CTTID 2 WRITEDATATOFILE("@rem ***********************************************************\n"); WRITEDATATOFILE("@rem CTT -> GTT\n"); WRITEDATATOFILE("@rem ***********************************************************\n"); pCTT_FileName = pCTT_FileNameSrc; for (dwI = 0; dwI < dwTotalNumOfCTT; dwI ++) { dwJ = 0; while(pCTT_FileName->wchFileName[dwJ] != '.' || pCTT_FileName->wchFileName[dwJ + 1] == '.' || pCTT_FileName->wchFileName[dwJ + 1] == '\\') { wchFileName1[dwJ] = pCTT_FileName->wchFileName[dwJ]; dwJ ++; } wchFileName1[dwJ] = (WCHAR)NULL; sprintf((PSTR)aubBuff, "ctt2gtt %ws.txt %ws.ctt %ws.gtt\n", wchFileName1, wchFileName1, wchFileName1); WRITEDATATOFILE(aubBuff); (PBYTE)pCTT_FileName += pCTT_FileName->wNext; } WRITEDATATOFILE("@rem ***********************************************************\n"); sprintf((PSTR)aubBuff, "@rem Model ID : %d\n", pModelFontList->sID); WRITEDATATOFILE(aubBuff); sprintf((PSTR)aubBuff, "@rem Model Name String ID : %d\n", pModelFontList->sStringID); WRITEDATATOFILE(aubBuff); WRITEDATATOFILE("@rem ***********************************************************\n"); WRITEDATATOFILE("@rem Resident font\n"); WRITEDATATOFILE("@rem ***********************************************************\n"); psFontID = (PSHORT)(pModelFontList->psResFontList); for (dwI = 1; dwI <= pModelFontList->dwNumOfResFont; dwI++, psFontID++) { sCTTID = SGetCTTID(dwTotalNumOfPFM, *psFontID, pPFM_ID); if (sCTTID == (SHORT)0x8FFF) { WRITEDATATOFILE("Invalid CTT ID\n"); } else { if (sCTTID == 0) { sCTTID = pModelFontList->sDefaultCTT; } pcwstrPFMFileName = PcwstrGetFileName(*psFontID, pPFM_FileNameSrc, dwTotalNumOfPFM); pcwstrCTTFileName = PcwstrGetFileName(sCTTID, pCTT_FileNameSrc, dwTotalNumOfCTT); if (pcwstrPFMFileName != NULL) { if (pcwstrCTTFileName) { dwJ = 0; while(pcwstrCTTFileName[dwJ] != '.' || pcwstrCTTFileName[dwJ + 1] == '.' || pcwstrCTTFileName[dwJ + 1] == '\\' ) { wchFileName1[dwJ] = pcwstrCTTFileName[dwJ]; dwJ ++; } wchFileName1[dwJ] = (WCHAR)NULL; dwPFM2UFMMode = PFM2UFM_GTTMODE; } else if (sCTTID == 0) { dwPFM2UFMMode = PFM2UFM_CODEPAGE; dwCodePage = 1252; } else if (-3 <= sCTTID && sCTTID <= -1) { dwPFM2UFMMode = PFM2UFM_DEF_CTTID; } else if (-263 <= sCTTID && sCTTID <= -256) { dwPFM2UFMMode = PFM2UFM_CODEPAGE; dwCodePage = DwCTTID2CodePage(sCTTID); } dwJ = 0; while(pcwstrCTTFileName[dwJ] != '.' || pcwstrCTTFileName[dwJ + 1] == '.' || pcwstrCTTFileName[dwJ + 1] == '\\') { wchFileName2[dwJ] = pcwstrPFMFileName[dwJ]; dwJ ++; } wchFileName2[dwJ] = (WCHAR)NULL; if (dwPFM2UFMMode == PFM2UFM_GTTMODE) { sprintf((PSTR)aubBuff, "pfm2ufm UniqName %ws %ws.gtt %ws.ufm\n", pcwstrPFMFileName, wchFileName1, wchFileName2); } else if (dwPFM2UFMMode == PFM2UFM_CODEPAGE) { sprintf((PSTR)aubBuff, "pfm2ufm -c UniqName %ws %d %ws.ufm\n", pcwstrPFMFileName, dwCodePage, wchFileName2); } if (dwPFM2UFMMode == PFM2UFM_DEF_CTTID) { sprintf((PSTR)aubBuff, "pfm2ufm -p UniqName %ws %d %ws.ufm\n", pcwstrPFMFileName, -sCTTID, wchFileName2); } WRITEDATATOFILE(aubBuff); } else { sprintf((PSTR)aubBuff, "Error: FontID=%d, CTTID=%d\n", *psFontID, sCTTID); WRITEDATATOFILE(aubBuff); } } } if (pModelFontList->dwNumOfCart) { WRITEDATATOFILE("@rem ***********************************************************\n"); WRITEDATATOFILE("@rem Cartridge font list\n"); } pCartFontList = (PCART_FONTLIST)pModelFontList->dwCartList; for (dwI = 0; dwI < pModelFontList->dwNumOfCart; dwI ++, pCartFontList++) { WRITEDATATOFILE("@rem ***********************************************************\n"); sprintf((PSTR)aubBuff, "@rem CartridgeID = %d\n", pCartFontList->sID); WRITEDATATOFILE(aubBuff); sprintf((PSTR)aubBuff, "@rem StringID = %d\n", pCartFontList->sStringID); WRITEDATATOFILE(aubBuff); sprintf((PSTR)aubBuff, "@rem Number of fonts = %d\n", pCartFontList->dwNumCartFont); WRITEDATATOFILE(aubBuff); WRITEDATATOFILE("@rem -----------------------------------------------------------\n"); psFontID = (PSHORT)((PBYTE)pCartFontList + pCartFontList->dwFontList); for (dwJ = 0; dwJ < pCartFontList->dwNumCartFont; dwJ ++, psFontID++) { sCTTID = SGetCTTID(dwTotalNumOfPFM, *psFontID, pPFM_ID); if (sCTTID == (SHORT)0x8FFF) { WRITEDATATOFILE("@rem Invalid CTT ID\n"); } else { if (sCTTID == 0) { sCTTID = pModelFontList->sDefaultCTT; } pcwstrPFMFileName = PcwstrGetFileName(*psFontID, pPFM_FileNameSrc, dwTotalNumOfPFM); pcwstrCTTFileName = PcwstrGetFileName(sCTTID, pCTT_FileNameSrc, dwTotalNumOfCTT); if (pcwstrPFMFileName != NULL) { if (pcwstrCTTFileName) { dwK = 0; while(pcwstrCTTFileName[dwK] != '.' || pcwstrCTTFileName[dwK + 1] == '.' || pcwstrCTTFileName[dwK + 1] == '\\') { wchFileName1[dwK] = pcwstrCTTFileName[dwK]; dwK ++; } wchFileName1[dwK] = (WCHAR)NULL; dwPFM2UFMMode = PFM2UFM_GTTMODE; } else if (sCTTID == 0) { dwPFM2UFMMode = PFM2UFM_CODEPAGE; } else if (-3 <= sCTTID && sCTTID <= -1) { dwPFM2UFMMode = PFM2UFM_DEF_CTTID; } else if (-263 <= sCTTID && sCTTID <= -256) { dwPFM2UFMMode = PFM2UFM_CODEPAGE; dwCodePage = DwCTTID2CodePage(sCTTID); } dwK = 0; while(pcwstrCTTFileName[dwK] != '.' || pcwstrCTTFileName[dwK + 1] == '.' || pcwstrCTTFileName[dwK + 1] == '\\') { wchFileName2[dwK] = pcwstrPFMFileName[dwK]; dwK ++; } wchFileName2[dwK] = (WCHAR)NULL; if (dwPFM2UFMMode == PFM2UFM_GTTMODE) { sprintf((PSTR)aubBuff, "pfm2ufm UniqName %ws %ws.gtt %ws.ufm\n", pcwstrPFMFileName, wchFileName1, wchFileName2); } else if (dwPFM2UFMMode == PFM2UFM_CODEPAGE) { sprintf((PSTR)aubBuff, "pfm2ufm -c UniqName %ws %d %ws.ufm\n", pcwstrPFMFileName, dwCodePage, wchFileName2); } if (dwPFM2UFMMode == PFM2UFM_DEF_CTTID) { sprintf((PSTR)aubBuff, "pfm2ufm -p UniqName %ws %d %ws.ufm\n", pcwstrPFMFileName, -sCTTID, wchFileName2); } WRITEDATATOFILE(aubBuff); } else { sprintf((PSTR)aubBuff, "Error: FontID=%d, CTTID=%d\n", *psFontID, sCTTID); WRITEDATATOFILE(aubBuff); } } } } } SHORT SCountFontNum( IN PDH pGPCData, IN WORD wFontListPort, IN WORD wFontListLand) { PSHORT psFontListPortSrc, psFontListPort, psFontListLand; SHORT sReturn, sI; BOOL bAdd; sReturn = 0; if (wFontListPort == (WORD)0) { return sReturn; } psFontListPortSrc = psFontListPort = (PSHORT)((PBYTE)pGPCData + pGPCData->loHeap + wFontListPort); if (*psFontListPort > 0) { sReturn = *(psFontListPort + 1) - *psFontListPort + 1; psFontListPort += 2; } while(*psFontListPort) { sReturn ++; psFontListPort ++; } psFontListLand = (PSHORT)((PBYTE)pGPCData + pGPCData->loHeap + wFontListLand); if (wFontListLand == (WORD)0) { return sReturn; } if (*psFontListLand > 0) { for (sI = *psFontListLand; sI <= *(psFontListLand + 1); sI ++) { sReturn += SAdditionalFont(sI, psFontListPortSrc); } psFontListLand +=2; while(*psFontListLand) { sReturn += SAdditionalFont(*psFontListLand, psFontListPortSrc); psFontListLand ++; } } return sReturn; } SHORT SAdditionalFont( IN SHORT sI, IN PSHORT psFontList) { SHORT sReturn; BOOL bFound; if (*psFontList <= sI && sI <= *(psFontList + 1)) { return 0; } psFontList += 2; bFound = FALSE; while(*psFontList) { if (sI == *psFontList) { return 0; } psFontList++; } return 1; } PCWSTR PcwstrGetFileName( SHORT sID, PFILE_NAME pFileName, DWORD dwTotal) { DWORD dwI; for (dwI = 0; dwI < dwTotal; dwI ++) { if (pFileName->sID == sID) { return pFileName->wchFileName; } (PBYTE)pFileName += pFileName->wNext; } return NULL; } DWORD DwCTTID2CodePage( SHORT sCTTID) { DWORD dwRet; switch (sCTTID) { case CTT_CP437: case CTT_CP850: case CTT_CP863: dwRet = 1252; break; case CTT_BIG5: dwRet = 950; break; case CTT_ISC: dwRet = 949; break; case CTT_JIS78: dwRet = 932; break; case CTT_JIS83: dwRet = 932; break; case CTT_JIS78_ANK: dwRet = 932; break; case CTT_JIS83_ANK: dwRet = 932; break; case CTT_NS86: dwRet = 950; break; case CTT_TCA: dwRet = 950; break; } return dwRet; }