You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
885 lines
26 KiB
885 lines
26 KiB
/*++
|
|
|
|
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;
|
|
}
|