|
|
/*++
Copyright (c) 1996-1997 Microsoft Corporation
Module Name:
cttconv.c
Abstract:
Convert Win 3.1 CTT format tables to NT's GTT spec.
Environment:
Windows NT PostScript driver
Revision History:
--*/
#include "precomp.h"
//
// Debug flags
//
#define SET_PRINT 0
#define SET_RIP 0
//
// Some macro definitions.
//
#define BBITS 8 /* Bits in a byte */
#define DWBITS (BBITS * sizeof( DWORD )) /* Bits in a DWORD */
#define DW_MASK (DWBITS - 1)
//
// Local
//
BYTE ubGetAnsi(WCHAR, INT, PWCHAR, PBYTE);
//
// Conversion function
//
BOOL BConvertCTT2GTT( IN HANDLE hHeap, IN PTRANSTAB pCTTData, IN DWORD dwCodePage, IN WCHAR wchFirst, IN WCHAR wchLast, IN PBYTE pCPSel, IN PBYTE pCPUnSel, IN OUT PUNI_GLYPHSETDATA *ppGlyphSetData, IN DWORD dwGlySize) /*++
Routine Description:
Conversion from CTT to GLYPHSETDATA
Arguments:
hHeap - Heap handle pCTTData - Pointer to the 3.1 format translate table dwCodePage - additonal codepage pCPSel - symbol set selection command null terminate string. pCPUnsel - symbol set selection command null terminate string. ppGlyphSetData - Pointer to the GlyphSetData pointer
Return Value:
If TRUE, function succeeded. Othewise FALSE.
Note:
Allocates memory from the heap for this.
--*/ { UNI_CODEPAGEINFO CodePageInfo; UNI_GLYPHSETDATA GlyphSetData; PGLYPHRUN pOldGlyphRun, pOldGlyphFirst, pNewGlyphRun, pNewGlyphFirst; PMAPTABLE pOldMapTable, pNewMapTable; PUNI_CODEPAGEINFO pOldCodePageInfo; TRANSDATA *pTrans;
WCHAR awchUnicode[ 256 ]; // Converted array of points
WCHAR wchMin; /* Find the first unicode value */ WCHAR wchMax; /* Find the last unicode value */ WCHAR wchChar;
DWORD *pdwBits; /* For figuring out runs */ DWORD dwFlags; DWORD dwOldCodePageCount; DWORD dwOldCPCmdSize; DWORD dwI; DWORD dwcbBits; /* Size of this area */ DWORD dwMapTableCommandOffset;
WORD wType; WORD wcbData; WORD wI;
INT iI, iJ; // Loop index
INT iIndex; INT iNumOfHandle; // The number of handles we need
INT iNumOfHandleInCTT; // The number of handles in CTT
INT iTotalOffsetCmd; INT iTotalGlyphSetDataSize; INT iTotalCommandSize; INT iAdditionalGlyphRun; INT iAdditionalMapTable; INT iSizeOfSelUnsel; INT iNumOfRuns; /* Number of runs we create */
BYTE aubAnsi[ 256 ]; BYTE *pbBase; BYTE ubCodePageID; BYTE *pMapTableCommand; BYTE *pubData; BYTE ubAnsi;
BOOL bInRun; /* For processing run accumulations */
#define DWFLAGS_NEWCREATION 0x00000001
//
// Assertion
//
ASSERT(hHeap != NULL && pCTTData != NULL);
//
// Check if this is additional CTT.
//
#if 0
if (*ppGlyphSetData == 0 || dwGlySize == 0) { dwFlags = DWFLAGS_NEWCREATION; } else { dwFlags = 0; } #else
dwFlags = DWFLAGS_NEWCREATION; #endif
//
// 1. Create UNI_GLYPHSETDATA header
// 2. Count total size of command in CTT.
// 3. Create Unicode table
// 4. Get min and max Unicode value
// 5. Create Unicode bits table from CTT.
// 6. Count the number of run.
// 7. Create GLYPHRUN.
// 8. Create UNI_CODEPAGEINFO.
// 9. Calculate total size of this file.
// 10. Allocate memory for header, GLYPYRUN, CODEPAGEINFO
// 11. Create MAPTABLE
//
//
//
// 1. Initialize basic members of GLYPHSETDATA if necessary
//
//
#if SET_RIP
RIP(("1. Initialize basic members of GLYPHSETDATA if necessary.\n")); #elif SET_PRINT
printf("1. Initialize basic members of GLYPHSETDATA if necessary.\n"); #endif
if (dwFlags & DWFLAGS_NEWCREATION) { GlyphSetData.dwVersion = UNI_GLYPHSETDATA_VERSION_1_0; GlyphSetData.dwFlags = 0; GlyphSetData.lPredefinedID = CC_NOPRECNV; GlyphSetData.dwGlyphCount = 0; GlyphSetData.dwRunCount = 0; GlyphSetData.dwCodePageCount = 1; GlyphSetData.loCodePageOffset = (DWORD)0; GlyphSetData.loMapTableOffset = (DWORD)0;
} else { GlyphSetData.dwVersion = (*ppGlyphSetData)->dwVersion; GlyphSetData.dwFlags = (*ppGlyphSetData)->dwFlags; GlyphSetData.lPredefinedID = (*ppGlyphSetData)->lPredefinedID; GlyphSetData.dwGlyphCount = (*ppGlyphSetData)->dwGlyphCount; GlyphSetData.dwRunCount = (*ppGlyphSetData)->dwRunCount; GlyphSetData.dwCodePageCount = (*ppGlyphSetData)->dwCodePageCount + 1; GlyphSetData.loCodePageOffset = (DWORD)0; GlyphSetData.loMapTableOffset = (DWORD)0;
dwOldCodePageCount = (*ppGlyphSetData)->dwCodePageCount; pOldGlyphFirst = pOldGlyphRun = (PGLYPHRUN)((PBYTE)*ppGlyphSetData+ (*ppGlyphSetData)->loRunOffset); pOldCodePageInfo = (PUNI_CODEPAGEINFO)((PBYTE)*ppGlyphSetData+ (*ppGlyphSetData)->loCodePageOffset); pOldMapTable = (PMAPTABLE)((PBYTE)*ppGlyphSetData + (*ppGlyphSetData)->loMapTableOffset); }
//
// 2. Total size of WTYPE_OFFSET format command in CTT.
//
#if SET_RIP
RIP(("2. Count total number of run in CTT.\n")); #elif SET_PRINT
printf("2. Count total number of run in CTT.\n"); #endif
wchFirst = min(pCTTData->chFirstChar, wchFirst); wchLast = max(pCTTData->chLastChar, wchLast);
GlyphSetData.dwGlyphCount = iNumOfHandle = wchLast - wchFirst + 1; iNumOfHandleInCTT = pCTTData->chLastChar - pCTTData->chFirstChar + 1;
switch (pCTTData->wType) { case CTT_WTYPE_COMPOSE: iTotalOffsetCmd = pCTTData->uCode.psCode[iNumOfHandleInCTT] - pCTTData->uCode.psCode[0] + iNumOfHandleInCTT * 2; break; case CTT_WTYPE_DIRECT: iTotalOffsetCmd = 0; break;
case CTT_WTYPE_PAIRED: iTotalOffsetCmd = 0; break; }
//
// 3. Create Unicode table
// We need to figure out how many runs are required to describe
// this font. First obtain the correct Unicode encoding of these
// values, then examine them to find the number of runs, and
// hence much extra storage is required.
//
#if SET_RIP
RIP(("3. Create Unicode table.\n")); #elif SET_PRINT
printf("3. Create Unicode table.\n"); #endif
//
// We know it is < 256
//
for( iI = 0; iI < iNumOfHandle; ++iI ) aubAnsi[ iI ] = (BYTE)(iI + wchFirst);
#ifdef NTGDIKM
if( -1 == EngMultiByteToWideChar(dwCodePage, awchUnicode, (ULONG)(iNumOfHandle * sizeof(WCHAR)), (PCH) aubAnsi, (ULONG) iNumOfHandle)) { return FALSE; }
#else
if( ! MultiByteToWideChar(dwCodePage, 0, aubAnsi, iNumOfHandle, awchUnicode, iNumOfHandle)) { return FALSE; }
#endif
//
// 4. Get min and max Unicode value
// Find the largest Unicode value, then allocate storage to allow us
// to create a bit array of valid unicode points. Then we can
// examine this to determine the number of runs.
//
#if SET_RIP
RIP(("4. Get min and max Unicode value.\n")); #elif SET_PRINT
printf("4. Get min and max Unicode value.\n"); #endif
for( wchMax = 0, wchMin = 0xffff, iI = 0; iI < iNumOfHandle; ++iI ) { if( awchUnicode[ iI ] > wchMax ) wchMax = awchUnicode[ iI ]; if( awchUnicode[ iI ] < wchMin ) wchMin = awchUnicode[ iI ]; }
//
// 5. Create Unicode bits table from CTT.
// Note that the expression 1 + wchMax IS correct. This comes about
// from using these values as indices into the bit array, and that
// this is essentially 1 based.
//
#if SET_RIP
RIP(("5. Create Unicode bits table from CTT.\n")); #elif SET_PRINT
printf("5. Create Unicode bits table from CTT.\n"); #endif
dwcbBits = (1 + wchMax + DWBITS - 1) / DWBITS * sizeof( DWORD );
if( !(pdwBits = (DWORD *)HeapAlloc( hHeap, 0, dwcbBits )) ) { return FALSE; /* Nothing going */ }
ZeroMemory( pdwBits, dwcbBits );
//
// Set bits in this array corresponding to Unicode code points
//
for( iI = 0; iI < iNumOfHandle; ++iI ) { pdwBits[ awchUnicode[ iI ] / DWBITS ] |= (1 << (awchUnicode[ iI ] & DW_MASK)); }
//
//
// 6. Count the number of run.
//
//
#if SET_RIP
RIP(("6. Count the number of run.\n")); #elif SET_PRINT
printf("6. Count the number of run.\n"); #endif
if (dwFlags & DWFLAGS_NEWCREATION) { //
// Now we can examine the number of runs required. For starters,
// we stop a run whenever a hole is discovered in the array of 1
// bits we just created. Later we MIGHT consider being a little
// less pedantic.
//
bInRun = FALSE; iNumOfRuns = 0;
for( iI = 0; iI <= (INT)wchMax; ++iI ) { if( pdwBits[ iI / DWBITS ] & (1 << (iI & DW_MASK)) ) { /* Not in a run: is this the end of one? */ if( !bInRun ) { /* It's time to start one */ bInRun = TRUE; ++iNumOfRuns;
}
} else { if( bInRun ) { /* Not any more! */ bInRun = FALSE; } } }
GlyphSetData.dwRunCount = iNumOfRuns;
} else { //
// CTT addition case
//
iNumOfRuns = (*ppGlyphSetData)->dwRunCount;
//
// Merge CTT and GlyphRun
//
for (iI = 0; iI < iNumOfRuns; iI ++) { for (iJ = 0; iJ < pOldGlyphRun->wGlyphCount; iJ ++) { INT iGlyph = iJ + pOldGlyphRun->wcLow;
pdwBits[ iGlyph / DWBITS ] |= (1 << (iGlyph & DW_MASK)); }
pOldGlyphRun++; }
bInRun = FALSE; iNumOfRuns = 0; iNumOfHandle = 0;
for( iI = 0; iI <= (INT)wchMax; ++iI ) { if( pdwBits[ iI / DWBITS ] & (1 << (iI & DW_MASK)) ) { /* Not in a run: is this the end of one? */ if( !bInRun ) { /* It's time to start one */ bInRun = TRUE; ++iNumOfRuns;
} iNumOfHandle ++;
} else { if( bInRun ) { /* Not any more! */ bInRun = FALSE; } } } }
//
// 7. Create GLYPHRUN
//
#if SET_RIP
RIP(("7. Create GLYPHRUN.\n")); #elif SET_PRINT
printf("7. Create GLYPHRUN.\n"); #endif
if( !(pNewGlyphFirst = pNewGlyphRun = (PGLYPHRUN)HeapAlloc( hHeap, 0, iNumOfRuns * sizeof(GLYPHRUN) )) ) { return FALSE; /* Nothing going */ }
bInRun = FALSE;
for (wI = 0; wI <= wchMax; wI ++) { if (pdwBits[ wI / DWBITS ] & (1 << (wI & DW_MASK)) ) { if (!bInRun) { bInRun = TRUE; pNewGlyphRun->wcLow = wI ; pNewGlyphRun->wGlyphCount = 1; } else { pNewGlyphRun->wGlyphCount++; } } else {
if (bInRun) { bInRun = FALSE; pNewGlyphRun++; } } }
pNewGlyphRun = pNewGlyphFirst;
//
//
// 8. Create UNI_CODEPAGEINFO.
//
//
#if SET_RIP
RIP(("8. Create UNI_CODEPAGEINFO.\n")); #elif SET_PRINT
printf("8. Create UNI_CODEPAGEINFO.\n"); #endif
CodePageInfo.dwCodePage = dwCodePage;
if (pCPSel) { CodePageInfo.SelectSymbolSet.dwCount = strlen(pCPSel) + 1; } else { CodePageInfo.SelectSymbolSet.dwCount = 0; }
if (pCPUnSel) { CodePageInfo.UnSelectSymbolSet.dwCount = strlen(pCPUnSel) + 1; } else { CodePageInfo.UnSelectSymbolSet.dwCount = 0; }
if (dwFlags & DWFLAGS_NEWCREATION) { if (pCPSel) { CodePageInfo.SelectSymbolSet.loOffset = sizeof(UNI_CODEPAGEINFO); } else { CodePageInfo.SelectSymbolSet.loOffset = 0; } if (pCPUnSel) { CodePageInfo.UnSelectSymbolSet.loOffset = sizeof(UNI_CODEPAGEINFO) + CodePageInfo.SelectSymbolSet.dwCount; } else { CodePageInfo.UnSelectSymbolSet.loOffset = 0; } } else {
dwOldCPCmdSize = 0;
for (dwI = 0; dwI < dwOldCodePageCount; dwI++) { dwOldCPCmdSize += (pOldCodePageInfo+dwI)->SelectSymbolSet.dwCount + (pOldCodePageInfo+dwI)->UnSelectSymbolSet.dwCount; (pOldCodePageInfo+dwI)->SelectSymbolSet.loOffset += sizeof(UNI_CODEPAGEINFO); (pOldCodePageInfo+dwI)->UnSelectSymbolSet.loOffset += sizeof(UNI_CODEPAGEINFO); }
CodePageInfo.SelectSymbolSet.loOffset = sizeof(UNI_CODEPAGEINFO) + dwOldCPCmdSize; CodePageInfo.UnSelectSymbolSet.loOffset = sizeof(UNI_CODEPAGEINFO) + dwOldCPCmdSize + CodePageInfo.SelectSymbolSet.dwCount; }
//
//
// 9. Calculate total size of this file.
//
//
#if SET_RIP
RIP(("9. Calculate total size of this file.\n")); #elif SET_PRINT
printf("9. Calculate total size of this file.\n"); #endif
iSizeOfSelUnsel = CodePageInfo.SelectSymbolSet.dwCount + CodePageInfo.UnSelectSymbolSet.dwCount;
if (dwFlags & DWFLAGS_NEWCREATION) {
iTotalGlyphSetDataSize = sizeof(UNI_GLYPHSETDATA) + sizeof(UNI_CODEPAGEINFO) + iSizeOfSelUnsel + iNumOfRuns * sizeof( GLYPHRUN ) + sizeof(MAPTABLE) + (iNumOfHandle - 1) * sizeof(TRANSDATA) + iTotalOffsetCmd; } else { iTotalGlyphSetDataSize = sizeof(UNI_GLYPHSETDATA) + dwOldCodePageCount * sizeof(UNI_CODEPAGEINFO) + sizeof(UNI_CODEPAGEINFO) + dwOldCPCmdSize + iSizeOfSelUnsel + iNumOfRuns * sizeof( GLYPHRUN ) + sizeof(MAPTABLE) + (iNumOfHandle - 1) * sizeof(TRANSDATA); }
//
//
// 10. Allocate memory and set header, copy GLYPHRUN, CODEPAGEINFO
//
//
#if SET_RIP
RIP(("10. Allocate memory and set header, copy GLYPHRUN, CODEPAGEINFO.\n")); #elif SET_PRINT
printf("10. Allocate memory and set header, copy GLYPHRUN, CODEPAGEINFO.\n"); #endif
if( !(pbBase = HeapAlloc( hHeap, 0, iTotalGlyphSetDataSize )) ) { HeapFree( hHeap, 0, (LPSTR)pbBase ); return FALSE; }
ZeroMemory( pbBase, iTotalGlyphSetDataSize ); //Safer if we miss something
if (dwFlags & DWFLAGS_NEWCREATION) { GlyphSetData.dwSize = iTotalGlyphSetDataSize; GlyphSetData.loRunOffset = sizeof(UNI_GLYPHSETDATA); GlyphSetData.loCodePageOffset = sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns; GlyphSetData.loMapTableOffset = sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns + sizeof(UNI_CODEPAGEINFO) + CodePageInfo.SelectSymbolSet.dwCount + CodePageInfo.UnSelectSymbolSet.dwCount; CopyMemory(pbBase, &GlyphSetData, sizeof(UNI_GLYPHSETDATA));
CopyMemory(pbBase+sizeof(UNI_GLYPHSETDATA), pNewGlyphRun, sizeof(GLYPHRUN) * iNumOfRuns);
CopyMemory(pbBase + GlyphSetData.loCodePageOffset, &CodePageInfo, sizeof(UNI_CODEPAGEINFO));
if (pCPSel) { CopyMemory(pbBase + GlyphSetData.loCodePageOffset + sizeof(UNI_CODEPAGEINFO), pCPSel, CodePageInfo.SelectSymbolSet.dwCount); }
if (pCPUnSel) { CopyMemory(pbBase + GlyphSetData.loCodePageOffset + sizeof(UNI_CODEPAGEINFO) + CodePageInfo.SelectSymbolSet.dwCount, pCPUnSel, CodePageInfo.UnSelectSymbolSet.dwCount); }
pNewMapTable = (PMAPTABLE)(pbBase + GlyphSetData.loMapTableOffset); } else { GlyphSetData.dwSize = iTotalGlyphSetDataSize; GlyphSetData.loRunOffset = sizeof(UNI_GLYPHSETDATA); GlyphSetData.loCodePageOffset = sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns; GlyphSetData.loMapTableOffset = sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns + sizeof(UNI_CODEPAGEINFO) * (dwOldCodePageCount + 1), dwOldCPCmdSize + CodePageInfo.SelectSymbolSet.dwCount + CodePageInfo.UnSelectSymbolSet.dwCount;
CopyMemory(pbBase, &GlyphSetData, sizeof(UNI_GLYPHSETDATA));
CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA), pNewGlyphRun, iNumOfRuns * sizeof (GLYPHRUN));
CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns, pOldCodePageInfo, sizeof(UNI_CODEPAGEINFO) * dwOldCodePageCount);
CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns + sizeof(UNI_CODEPAGEINFO) * dwOldCodePageCount, &CodePageInfo, sizeof(UNI_CODEPAGEINFO));
CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns + sizeof(UNI_CODEPAGEINFO) * (dwOldCodePageCount + 1), (PBYTE)pOldCodePageInfo + sizeof(UNI_CODEPAGEINFO) * dwOldCodePageCount, dwOldCPCmdSize);
if (pCPSel) { CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN) * iNumOfRuns + sizeof(UNI_CODEPAGEINFO) * (dwOldCodePageCount + 1) + dwOldCPCmdSize, pCPSel, CodePageInfo.SelectSymbolSet.dwCount); }
if (pCPUnSel) { CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA) + sizeof(GLYPHRUN)*iNumOfRuns + sizeof(UNI_CODEPAGEINFO) * (dwOldCodePageCount + 1) + dwOldCPCmdSize + CodePageInfo.SelectSymbolSet.dwCount, pCPUnSel, CodePageInfo.UnSelectSymbolSet.dwCount); }
pNewMapTable = (PMAPTABLE)(pbBase + GlyphSetData.loMapTableOffset); }
//
//
// 11. Now we create MAPTABLE.
// size = MAPTABLE + (number of glyph - 1) x TRANSDATA
//
//
#if SET_RIP
RIP(("11. Now We create MAPTABLE.\n")); #elif SET_PRINT
printf("11. Now We create MAPTABLE.\n"); #endif
pNewMapTable->dwSize = sizeof(MAPTABLE) + (iNumOfHandle - 1) * sizeof(TRANSDATA) + iTotalOffsetCmd;
pNewMapTable->dwGlyphNum = iNumOfHandle;
pNewGlyphRun = pNewGlyphFirst;
pTrans = pNewMapTable->Trans;
if (dwFlags & DWFLAGS_NEWCREATION) ubCodePageID = 0; else ubCodePageID = (BYTE)((*ppGlyphSetData)->dwCodePageCount) - 1;
pMapTableCommand = (PBYTE)&(pNewMapTable->Trans[iNumOfHandle]); dwMapTableCommandOffset = sizeof(MAPTABLE) + (iNumOfHandle - 1) * sizeof(TRANSDATA);
iTotalCommandSize = 0; iIndex = 0;
for( iI = 0; iI < iNumOfRuns; iI ++, pNewGlyphRun ++) { for( iJ = 0; iJ < pNewGlyphRun->wGlyphCount; iJ ++) { wchChar = pNewGlyphRun->wcLow + iJ;
ubAnsi = ubGetAnsi(wchChar, iNumOfHandle, awchUnicode, aubAnsi); if( ubAnsi >= pCTTData->chFirstChar && ubAnsi <= pCTTData->chLastChar ) { BYTE chTemp;
chTemp = ubAnsi - pCTTData->chFirstChar;
switch( pCTTData->wType ) { case CTT_WTYPE_DIRECT: pTrans[iIndex].ubCodePageID = ubCodePageID; pTrans[iIndex].ubType = MTYPE_DIRECT; pTrans[iIndex].uCode.ubCode = pCTTData->uCode.bCode[ chTemp ]; break;
case CTT_WTYPE_PAIRED: pTrans[iIndex].ubCodePageID = ubCodePageID; pTrans[iIndex].ubType = MTYPE_PAIRED; pTrans[iIndex].uCode.ubPairs[0] = pCTTData->uCode.bPairs[ chTemp ][ 0 ]; pTrans[iIndex].uCode.ubPairs[1] = pCTTData->uCode.bPairs[ chTemp ][ 1 ]; break;
case CTT_WTYPE_COMPOSE: wcbData = pCTTData->uCode.psCode[ chTemp + 1 ] - pCTTData->uCode.psCode[ chTemp ]; pubData = (BYTE *)pCTTData + pCTTData->uCode.psCode[chTemp];
pTrans[iIndex].ubCodePageID = ubCodePageID; pTrans[iIndex].ubType = MTYPE_COMPOSE; pTrans[iIndex].uCode.sCode = (SHORT)dwMapTableCommandOffset;
#if SET_PRINT
{ DWORD dwK;
printf("ubAnsi = 0x%x\n", ubAnsi); printf("Offset = 0x%x\n", dwMapTableCommandOffset); printf("Size = %d\n", wcbData); printf("Command = "); for (dwK = 0; dwK < wcbData; dwK ++) { printf("%02x", pubData[dwK]); } } printf("\n"); #endif
*(WORD*)pMapTableCommand = (WORD)wcbData; pMapTableCommand += 2; CopyMemory(pMapTableCommand, pubData, wcbData); pMapTableCommand += wcbData; dwMapTableCommandOffset += 2 + wcbData; iTotalCommandSize += wcbData + 2; break; } } else { pTrans[iIndex].ubCodePageID = ubCodePageID; pTrans[iIndex].ubType = MTYPE_DIRECT; pTrans[iIndex].uCode.ubCode = ubAnsi; }
iIndex++; } }
//
//
// Set pointer.
//
//
*ppGlyphSetData = (PUNI_GLYPHSETDATA)pbBase;
return TRUE;
}
BYTE ubGetAnsi( WCHAR wchChar, INT iNumOfHandle, PWCHAR pwchUnicode, PBYTE pchAnsi) {
BYTE ubRet; INT iI;
for (iI = 0; iI < iNumOfHandle; iI ++) { if (wchChar == pwchUnicode[iI]) { ubRet = pchAnsi[iI]; break; } }
return ubRet; }
|