Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1361 lines
37 KiB

/*++
Copyright (c) 1996 Adobe Systems Incorporated
Copyright (c) 1996 Microsoft Corporation
Module Name:
cjkfonts.c
Abstract:
Convert CJK AFMs to NTMs.
Environment:
Windows NT PostScript driver: makentf utility.
Revision History:
02/10/98 -ksuzuki-
Added OCF font support using 83pv font; did code cleanup, especially
of the CreateCJKGlyphSets function.
01/13/96 -rkiesler-
Wrote it.
-*/
#include "lib.h"
#include "ppd.h"
#include "pslib.h"
#include "psglyph.h"
#include "afm2ntm.h"
#include "cjkfonts.h"
#include "winfont.h"
extern BOOL bVerbose;
ULONG
CreateCJKGlyphSets(
PBYTE *pUV2CCMaps,
PBYTE *pUV2CIDMaps,
PGLYPHSETDATA *pGlyphSets,
PWINCODEPAGE pWinCodePage,
PULONG *pUniPsTbl
)
/*++
Routine Description:
Given memory mapped file ptrs to H and V Unicode to CharCode map files
and H and V Unicode to CID map files, create 2 GLYPHSETDATA structures
which represent H and V variants of the character collection. Create
ptrs to 2 tables which map glyph indices to CIDs for each variant.
Arguments:
pUV2CCMaps - Pointer to two memory mapped map files. These map Unicode
value to corresponding character code. pUV2CCMaps[0] and pUV2CCMaps[1]
for H and V respectively.
pUV2CIDMaps - Pointer to two memory mapped map files. These Unicode to
corresponding CID. pUV2CIDMaps[0] and pUV2CIDMaps[1] for H and V
respectively.
pGlyphSets - two position array of GLYPHSETDATA pointers which upon
successful completion contain the addresses of the newly allocated
GLYPHSETDATA structs representing the H and V variants of the char
collection.
pWinCodePage - Pts to a WINCODEPAGE struct which provides Windows
specific info about this charset.
pUniPsTbl - two position array of ULONG ptrs which each pts to a table
which maps 0-based Glyph Indices of chars in the GLYPHRUNS of the
GLYPHSETDATA for this char collection to CIDs.
Return Value:
TRUE => success.
FALSE => error.
--*/
{
PBYTE pToken, pGlyphSetName;
ULONG cChars, cRuns, cRanges, curCID;
USHORT cCharRun;
PGLYPHRUN pGlyphRuns;
PCMAP pUv2CcMap[NUM_VARIANTS];
PCMAP pUv2CidMap[NUM_VARIANTS];
ULONG c, i, uv;
PVOID pMapTbl;
PCMAPRANGE pCMapRange;
PCMAP pSrchCMap;
ULONG cGlyphSetBytes[NUM_VARIANTS], cSizeBytes[NUM_VARIANTS];
BOOLEAN bFound, bInRun;
USHORT wcRunStrt;
DWORD dwGSNameSize, dwCodePageInfoSize, dwGlyphRunSize, dwCPIGSNameSize;
DWORD dwEncodingNameOffset;
PCODEPAGEINFO pCodePageInfo;
BOOL bSingleCodePage;
if (bVerbose) printf("%%%%[Begin Create CJK glyphset]%%%%\n\n");
//////////////////////////////////////////////////////////////////////////
//
// Create the local Unicode->CharCode and Unicode->CID Maps sorted in
// starting Unicode order.
//
//////////////////////////////////////////////////////////////////////////
//
// Get pointer to, and determine size of, the name strings for each variant.
//
for (i = 0; i < NUM_VARIANTS; i++)
{
//
// Process the Unicode->CharCode map to determine the number of its
// chars and runs.
//
if (NumUV2CCRuns(pUV2CCMaps[i], &cRuns, &cChars) == FALSE)
{
return(FALSE);
}
//
// Alloc memory for create local CMap structs needed to build
// GLYPHSETs.
//
pUv2CcMap[i] = (PCMAP)MemAllocZ(sizeof(CMAP) + sizeof(CMAPRANGE) * (cRuns - 1));
if (pUv2CcMap[i] == NULL)
{
ERR(("makentf - CreateCJKGlyphSets: MemAllocZ\n"));
return(FALSE);
}
pUv2CcMap[i]->cChars = cChars;
if (BuildUV2CCMap(pUV2CCMaps[i], pUv2CcMap[i]) == FALSE)
{
return(FALSE);
}
//
// Sort the CMap ranges in starting Unicode order.
//
qsort(pUv2CcMap[i]->CMapRange,
(size_t)pUv2CcMap[i]->cRuns,
(size_t)sizeof(CMAPRANGE),
CmpCMapRunsChCode);
//
// Process the Unicode->CID map to determine the number of its
// chars and runs.
//
if (NumUV2CIDRuns(pUV2CIDMaps[i], &cRuns, &cChars) == FALSE)
{
return(FALSE);
}
pUv2CidMap[i] = (PCMAP)MemAllocZ(sizeof(CMAP) + sizeof(CMAPRANGE) * (cRuns - 1));
if (pUv2CidMap[i] == NULL)
{
ERR(("makentf - CreateCJKGlyphSets: MemAllocZ\n"));
return(FALSE);
}
pUv2CidMap[i]->cChars = cChars;
if (BuildUV2CIDMap(pUV2CIDMaps[i], pUv2CidMap[i]) == FALSE)
{
return(FALSE);
}
//
// Sort CMap Ranges in Starting char code order.
//
qsort(pUv2CidMap[i]->CMapRange,
(size_t)pUv2CidMap[i]->cRuns,
(size_t)sizeof(CMAPRANGE),
CmpCMapRunsChCode);
}
//
// CJK fonts never have multiple codepages, but, we figure it out anyway
// just in case.
//
bSingleCodePage = (pWinCodePage->usNumBaseCsets == 1) ? TRUE : FALSE;
//////////////////////////////////////////////////////////////////////////
//
// Create H GLYPHSETDATA
//
//////////////////////////////////////////////////////////////////////////
//
// Count chars and runs in H CMaps.
//
// Look up all Unicode points in the H Unicode->CID map and the H Unicode->
// CharCode map to determine number of GLYPHRUNs required for the
// GLYPHSETDATA we are about to create.
//
cChars = cRuns = 0;
bInRun = bFound = FALSE;
for (uv = 0; uv < NUM_UNICODE_CHARS; uv++)
{
//
// Search for the Unicode value in H Unicode->CharCode map.
//
pCMapRange = (PCMAPRANGE)bsearch(&uv,
pUv2CidMap[H_CMAP]->CMapRange,
pUv2CidMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound)
{
//
// Found this unicode value in H Unicode->CID map. Determine if it
// maps to a CharCode in H Unicode->CharCode map.
//
bFound = (bsearch(&uv,
pUv2CcMap[H_CMAP]->CMapRange,
pUv2CcMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun) != NULL);
if (bFound)
{
cChars++;
}
}
//
// Determine if this is a new run.
//
bInRun = bFound && bInRun;
if (bFound && !bInRun)
{
cRuns++;
bInRun = TRUE;
}
}
//
// Compute amount of memory required for H GLYPHSET.
// Note to account for the H/V char appended to the GlyphSet name.
//
dwGSNameSize = ALIGN4(strlen(pWinCodePage->pszCPname) + 2);
dwCodePageInfoSize = ALIGN4(pWinCodePage->usNumBaseCsets * sizeof(CODEPAGEINFO));
dwGlyphRunSize = ALIGN4(cRuns * sizeof(GLYPHRUN));
cGlyphSetBytes[H_CMAP] = ALIGN4(sizeof(GLYPHSETDATA));
cGlyphSetBytes[H_CMAP] += dwGSNameSize;
cGlyphSetBytes[H_CMAP] += dwCodePageInfoSize;
cGlyphSetBytes[H_CMAP] += dwGlyphRunSize;
//
// Account for the size of the mapping table.
//
cGlyphSetBytes[H_CMAP] += bSingleCodePage ? ALIGN4((cChars * sizeof (WORD))) : (cChars * sizeof (DWORD));
//
// Account for size of CODEPAGE name strings found in CODEPAGEINFO
// struct(s).
//
for (dwCPIGSNameSize = 0, i = 0; i < pWinCodePage->usNumBaseCsets; i++)
{
dwCPIGSNameSize += ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1);
}
cGlyphSetBytes[H_CMAP] += dwCPIGSNameSize;
//
// Alloc memory for H GLYPHSET, Unicode->CID mapping table.
//
pGlyphSets[H_CMAP] = (PGLYPHSETDATA)MemAllocZ(cGlyphSetBytes[H_CMAP]);
if (pGlyphSets[H_CMAP] == NULL)
{
ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
return(FALSE);
}
pUniPsTbl[H_CMAP] = (PULONG)MemAllocZ(cChars * sizeof(ULONG));
if (pUniPsTbl[H_CMAP] == NULL)
{
ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
return(FALSE);
}
//
// Init GLYPHSETDATA for H.
//
pGlyphSets[H_CMAP]->dwSize = cGlyphSetBytes[H_CMAP];
pGlyphSets[H_CMAP]->dwVersion = GLYPHSETDATA_VERSION;
pGlyphSets[H_CMAP]->dwFlags = 0;
pGlyphSets[H_CMAP]->dwGlyphSetNameOffset = ALIGN4(sizeof(GLYPHSETDATA));
pGlyphSets[H_CMAP]->dwGlyphCount = cChars;
pGlyphSets[H_CMAP]->dwCodePageCount = pWinCodePage->usNumBaseCsets;
pGlyphSets[H_CMAP]->dwCodePageOffset = pGlyphSets[H_CMAP]->dwGlyphSetNameOffset + dwGSNameSize;
pGlyphSets[H_CMAP]->dwRunCount = cRuns;
pGlyphSets[H_CMAP]->dwRunOffset = pGlyphSets[H_CMAP]->dwCodePageOffset + dwCodePageInfoSize + dwCPIGSNameSize;
pGlyphSets[H_CMAP]->dwMappingTableOffset = pGlyphSets[H_CMAP]->dwRunOffset + dwGlyphRunSize;
//
// Set the mapping table type flag to dwFlags field.
//
pGlyphSets[H_CMAP]->dwFlags |= bSingleCodePage ? GSD_MTT_WCC : GSD_MTT_DWCPCC;
//
// Store GlyphSet name
//
pGlyphSetName = (PBYTE)MK_PTR(pGlyphSets[H_CMAP], dwGlyphSetNameOffset);
StringCchCopyA(pGlyphSetName, dwGSNameSize, pWinCodePage->pszCPname);
pGlyphSetName[strlen(pWinCodePage->pszCPname)] = 'H';
pGlyphSetName[strlen(pWinCodePage->pszCPname) + 1] = '\0';
//
// Initialize a CODEPAGEINFO struct for each base charset supported
// by this font.
//
pCodePageInfo = (PCODEPAGEINFO)MK_PTR(pGlyphSets[H_CMAP], dwCodePageOffset);
dwEncodingNameOffset = dwCodePageInfoSize;
for (i = 0; i < pWinCodePage->usNumBaseCsets; i++, pCodePageInfo++)
{
//
// Save CODEPAGEINFO name, id. We don't use PS encoding vectors.
//
pCodePageInfo->dwCodePage = aPStoCP[pWinCodePage->pCsetList[i]].usACP;
pCodePageInfo->dwWinCharset = (DWORD)aPStoCP[pWinCodePage->pCsetList[i]].jWinCharset;
pCodePageInfo->dwEncodingNameOffset = dwEncodingNameOffset;
pCodePageInfo->dwEncodingVectorDataSize = 0;
pCodePageInfo->dwEncodingVectorDataOffset = 0;
//
// Copy codepage name string to end of array of CODEPAGEINFOs.
//
StringCchCopyA((PBYTE)MK_PTR(pCodePageInfo, dwEncodingNameOffset),
ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1),
aPStoCP[pWinCodePage->pCsetList[i]].pGSName);
//
// Adjust the offset to the CodePage name for the next CODEPAGEINFO structure.
//
dwEncodingNameOffset -= ALIGN4(sizeof (CODEPAGEINFO));
dwEncodingNameOffset += ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1);
}
//
// Process H Unicode->CID/CharCode maps to determine the number of its
// chars and runs.
//
cRuns = 0;
cCharRun = 0;
bInRun = FALSE;
pGlyphRuns = GSD_GET_GLYPHRUN(pGlyphSets[H_CMAP]);
pMapTbl = GSD_GET_MAPPINGTABLE(pGlyphSets[H_CMAP]);
for (uv = c = 0; (uv < NUM_UNICODE_CHARS) && (c < cChars); uv++)
{
pCMapRange = bsearch(&uv,
pUv2CidMap[H_CMAP]->CMapRange,
pUv2CidMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound)
{
curCID = pCMapRange->CIDStrt + uv - pCMapRange->ChCodeStrt;
pCMapRange = bsearch(&uv,
pUv2CcMap[H_CMAP]->CMapRange,
pUv2CcMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound)
{
//
// Found this Unicode value in Unicode->CharCode map. Store in
// mapping table. Note that CJK fonts only support 1 charset
// per font.
//
pUniPsTbl[H_CMAP][c] = curCID;
if (bSingleCodePage)
{
if (pCMapRange != NULL)
((WORD*)pMapTbl)[c] = (WORD)(pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt));
else
((WORD*)pMapTbl)[c] = (WORD)uv;
}
else
{
((DWORD*)pMapTbl)[c] = aPStoCP[pWinCodePage->pCsetList[0]].usACP << 16;
if (pCMapRange != NULL)
{
((DWORD*)pMapTbl)[c] |= pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt);
}
else
{
((DWORD*)pMapTbl)[c] |= uv;
}
}
c++;
cCharRun++;
}
}
//
// Determine if this is a new Unicode run.
//
if (bFound && !bInRun)
{
//
// This is the beginning of a new run.
//
bInRun = TRUE;
pGlyphRuns[cRuns].wcLow = (USHORT) (uv & 0xffff);
}
//
// Determine if this is the end of a run.
//
if (bInRun && (!bFound || uv == NUM_UNICODE_CHARS || c == cChars))
{
//
// This is the end of a run.
//
bInRun = FALSE;
pGlyphRuns[cRuns].wGlyphCount = cCharRun;
cRuns++;
cCharRun = 0;
}
}
//////////////////////////////////////////////////////////////////////////
//
// Create V GLYPHSETDATA
//
//////////////////////////////////////////////////////////////////////////
//
// Count chars and runs in V maps.
//
// For the V GLYPHSETDATA, if a Unicode value is not found in V Unicode->
// CID map, we will then need to check H Unicode->CID map.
//
cChars = cRuns = 0;
bInRun = bFound = FALSE;
for (uv = 0; uv < NUM_UNICODE_CHARS; uv++)
{
//
// Search for the Unicode value in V, and then H Unicode->CID maps if
// not found.
//
pCMapRange = bsearch(&uv,
pUv2CidMap[V_CMAP]->CMapRange,
pUv2CidMap[V_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound == FALSE)
{
pCMapRange = bsearch(&uv,
pUv2CidMap[H_CMAP]->CMapRange,
pUv2CidMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
}
if (bFound)
{
//
// Found this unicode value. Determine if it maps to a CharCode in
// H or V Unicode->CharCode map.
//
pCMapRange = bsearch(&uv,
pUv2CcMap[V_CMAP]->CMapRange,
pUv2CcMap[V_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound == FALSE)
{
pCMapRange = bsearch(&uv,
pUv2CcMap[H_CMAP]->CMapRange,
pUv2CcMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
}
if (bFound)
{
cChars++;
}
}
//
// Determine if this is a new run.
//
bInRun = bFound && bInRun;
if (bFound && !bInRun)
{
cRuns++;
bInRun = TRUE;
}
}
//
// Compute amount of memory required for V GLYPHSET.
//
dwGSNameSize = ALIGN4(strlen(pWinCodePage->pszCPname) + 2);
dwCodePageInfoSize = ALIGN4(pWinCodePage->usNumBaseCsets * sizeof(CODEPAGEINFO));
dwGlyphRunSize = ALIGN4(cRuns * sizeof(GLYPHRUN));
cGlyphSetBytes[V_CMAP] = ALIGN4(sizeof(GLYPHSETDATA));
cGlyphSetBytes[V_CMAP] += dwGSNameSize;
cGlyphSetBytes[V_CMAP] += dwCodePageInfoSize;
cGlyphSetBytes[V_CMAP] += dwGlyphRunSize;
//
// Account for the size of the mapping table.
//
cGlyphSetBytes[V_CMAP] += bSingleCodePage ? ALIGN4((cChars * sizeof (WORD))) : (cChars * sizeof (DWORD));
//
// Account for size of CODEPAGE name strings found in CODEPAGEINFO
// struct(s).
//
for (dwCPIGSNameSize = 0, i = 0; i < pWinCodePage->usNumBaseCsets; i++)
{
dwCPIGSNameSize += ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1);
}
cGlyphSetBytes[V_CMAP] += dwCPIGSNameSize;
//
// Alloc memory for V GLYPHSET, Unicode->CID mapping table.
//
pGlyphSets[V_CMAP] = (PGLYPHSETDATA)MemAllocZ(cGlyphSetBytes[V_CMAP]);
if (pGlyphSets[V_CMAP] == NULL)
{
ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
return(FALSE);
}
pUniPsTbl[V_CMAP] = (PULONG)MemAllocZ(cChars * sizeof(ULONG));
if (pUniPsTbl[V_CMAP] == NULL)
{
ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
return(FALSE);
}
//
// Init GLYPHSETDATA for V.
//
pGlyphSets[V_CMAP]->dwSize = cGlyphSetBytes[V_CMAP];
pGlyphSets[V_CMAP]->dwVersion = GLYPHSETDATA_VERSION;
pGlyphSets[V_CMAP]->dwFlags = 0;
pGlyphSets[V_CMAP]->dwGlyphSetNameOffset = ALIGN4(sizeof(GLYPHSETDATA));
pGlyphSets[V_CMAP]->dwGlyphCount = cChars;
pGlyphSets[V_CMAP]->dwCodePageCount = pWinCodePage->usNumBaseCsets;
pGlyphSets[V_CMAP]->dwCodePageOffset = pGlyphSets[V_CMAP]->dwGlyphSetNameOffset + dwGSNameSize;
pGlyphSets[V_CMAP]->dwRunCount = cRuns;
pGlyphSets[V_CMAP]->dwRunOffset = pGlyphSets[V_CMAP]->dwCodePageOffset + dwCodePageInfoSize + dwCPIGSNameSize;
pGlyphSets[V_CMAP]->dwMappingTableOffset = pGlyphSets[V_CMAP]->dwRunOffset + dwGlyphRunSize;
//
// Set the mapping table type flag to dwFlags field.
//
pGlyphSets[V_CMAP]->dwFlags |= bSingleCodePage ? GSD_MTT_WCC : GSD_MTT_DWCPCC;
//
// Store GlyphSet name
//
pGlyphSetName = (PBYTE)MK_PTR(pGlyphSets[V_CMAP], dwGlyphSetNameOffset);
StringCchCopyA(pGlyphSetName, dwGSNameSize, pWinCodePage->pszCPname);
pGlyphSetName[strlen(pWinCodePage->pszCPname)] = 'V';
pGlyphSetName[strlen(pWinCodePage->pszCPname) + 1] = '\0';
//
// Initialize a CODEPAGEINFO struct for each base charset supported
// by this font.
//
pCodePageInfo = (PCODEPAGEINFO) MK_PTR(pGlyphSets[V_CMAP], dwCodePageOffset);
dwEncodingNameOffset = dwCodePageInfoSize;
for (i = 0; i < pWinCodePage->usNumBaseCsets; i++, pCodePageInfo++)
{
//
// Save CODEPAGEINFO name, id. We don't use PS encoding vectors.
//
pCodePageInfo->dwCodePage = aPStoCP[pWinCodePage->pCsetList[i]].usACP;
pCodePageInfo->dwWinCharset = (DWORD)aPStoCP[pWinCodePage->pCsetList[i]].jWinCharset;
pCodePageInfo->dwEncodingNameOffset = dwEncodingNameOffset;
pCodePageInfo->dwEncodingVectorDataSize = 0;
pCodePageInfo->dwEncodingVectorDataOffset = 0;
//
// Copy codepage name string to end of array of CODEPAGEINFOs.
//
StringCchCopyA((PBYTE)MK_PTR(pCodePageInfo, dwEncodingNameOffset),
ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1),
aPStoCP[pWinCodePage->pCsetList[i]].pGSName);
//
// Adjust the offset to the CodePage name for the next CODEPAGEINFO structure.
//
dwEncodingNameOffset -= sizeof(CODEPAGEINFO);
dwEncodingNameOffset += ALIGN4(strlen((PSZ)MK_PTR(pCodePageInfo, dwEncodingNameOffset)) + 1);
}
//
// Create V Glyphset by merging V and H Maps.
//
//
// Determine number of runs, chars in the Glyphset created when V and H
// Maps are merged.
//
cRuns = 0;
cCharRun = 0;
bInRun = bFound = FALSE;
pGlyphRuns = GSD_GET_GLYPHRUN(pGlyphSets[V_CMAP]);
pMapTbl = GSD_GET_MAPPINGTABLE(pGlyphSets[V_CMAP]);
for (uv = c = 0; (uv < NUM_UNICODE_CHARS) && (c < cChars); uv++)
{
pCMapRange = bsearch(&uv,
pUv2CidMap[V_CMAP]->CMapRange,
pUv2CidMap[V_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound == FALSE)
{
pCMapRange = bsearch(&uv,
pUv2CidMap[H_CMAP]->CMapRange,
pUv2CidMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
}
//
// Found this Unicode value. Determine if it maps to a CharCode in H
// or V Unicode->CC map.
//
if (bFound)
{
curCID = pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt);
pCMapRange = bsearch(&uv,
pUv2CcMap[V_CMAP]->CMapRange,
pUv2CcMap[V_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
if (bFound == FALSE)
{
pCMapRange = bsearch(&uv,
pUv2CcMap[H_CMAP]->CMapRange,
pUv2CcMap[H_CMAP]->cRuns,
sizeof(CMAPRANGE),
FindChCodeRun);
bFound = (pCMapRange != NULL);
}
if (bFound)
{
//
// Found this Unicode value in Unicode->CharCode map. Store in
// mapping table. Note that CJK fonts only support 1 charset
// per font.
//
pUniPsTbl[V_CMAP][c] = curCID;
if (bSingleCodePage)
{
if (pCMapRange != NULL)
((WORD*)pMapTbl)[c] = (WORD)(pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt));
else
((WORD*)pMapTbl)[c] = (WORD)uv;
}
else
{
((DWORD*)pMapTbl)[c] = aPStoCP[pWinCodePage->pCsetList[0]].usACP << 16;
if (pCMapRange != NULL)
{
((DWORD*)pMapTbl)[c] |= pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt);
}
else
{
((DWORD*)pMapTbl)[c] |= uv;
}
}
c++;
cCharRun++;
}
}
//
// Determine if this is a new Unicode run.
//
if (bFound && !bInRun)
{
//
// This is the beginning of a new run.
//
bInRun = TRUE;
pGlyphRuns[cRuns].wcLow = (USHORT) (uv & 0xffff);
}
//
// Determine if this is the end of a run.
//
if (bInRun && (!bFound || uv == NUM_UNICODE_CHARS || c == cChars))
{
//
// This is the end of a run.
//
bInRun = FALSE;
pGlyphRuns[cRuns].wGlyphCount = cCharRun;
cRuns++;
cCharRun = 0;
}
}
if (bVerbose)
{
for (i = 0; i < NUM_VARIANTS; i++)
{
printf("GLYPHSETDATA:dwFlags:%08X\n", pGlyphSets[i]->dwFlags);
printf("GLYPHSETDATA:dwGlyphSetNameOffset:%s\n",
(PSZ)MK_PTR(pGlyphSets[i], dwGlyphSetNameOffset));
printf("GLYPHSETDATA:dwGlyphCount:%ld\n", pGlyphSets[i]->dwGlyphCount);
printf("GLYPHSETDATA:dwRunCount:%ld\n", pGlyphSets[i]->dwRunCount);
printf("GLYPHSETDATA:dwCodePageCount:%ld\n", pGlyphSets[i]->dwCodePageCount);
{
DWORD dw;
PCODEPAGEINFO pcpi = (PCODEPAGEINFO)MK_PTR(pGlyphSets[i], dwCodePageOffset);
for (dw = 1; dw <= pGlyphSets[i]->dwCodePageCount; dw++)
{
printf("CODEPAGEINFO#%ld:dwCodePage:%ld\n", dw, pcpi->dwCodePage);
printf("CODEPAGEINFO#%ld:dwWinCharset:%ld\n", dw, pcpi->dwWinCharset);
printf("CODEPAGEINFO#%ld:dwEncodingNameOffset:%s\n",
dw, (PSZ)MK_PTR(pcpi, dwEncodingNameOffset));
pcpi++;
}
}
printf("\n");
}
}
//
// Clean-up: free the local Maps.
//
for (i = 0; i < NUM_VARIANTS; i++)
{
//
// Free temporary data structs.
//
if (pUv2CcMap[i] != NULL)
{
MemFree(pUv2CcMap[i]);
}
if (pUv2CidMap[i] != NULL)
{
MemFree(pUv2CidMap[i]);
}
}
if (bVerbose) printf("%%[End Create CJK glyphset]%%%%\n\n");
return(TRUE);
}
BOOLEAN
NumUV2CIDRuns(
PBYTE pCMapFile,
PULONG pcRuns,
PULONG pcChars
)
/*++
Routine Description:
Given a memory mapped file ptr to a Postscript CMap, determine
the number of CIDRanges (Runs) and total number of chars.
Arguments:
pCMapFile - Pointer to a memory mapped CMap file.
pcRuns - Pointer to a ULONG which will contain the number of runs.
pcChars - Pointer to a ULONG which will contain the number of chars.
Return Value:
TRUE => success
FALSE => error
--*/
{
PBYTE pToken;
ULONG cRanges, i;
USHORT chRunStrt, chRunEnd;
BYTE LineBuffer[25];
USHORT usLineLen;
*pcRuns = *pcChars = 0;
//
// Search for the CID ranges, and determine the number of runs and
// total number of chars in this GLYPHSET.
//
for (; (pCMapFile = FindStringToken(pCMapFile, CID_RANGE_TOK)) != NULL; )
{
GET_NUM_CID_RANGES(pCMapFile, cRanges);
*pcRuns += cRanges;
NEXT_LINE(pCMapFile);
for (i = 0; i < cRanges; i++)
{
PARSE_TOKEN(pCMapFile, pToken);
//
// Get begin and end range codes.
//
if (!AsciiToHex(pToken, &chRunStrt))
{
return(FALSE);
}
if (!AsciiToHex(pCMapFile, &chRunEnd))
{
return(FALSE);
}
//
// Compute size of run.
//
*pcChars += chRunEnd - chRunStrt + 1;
NEXT_LINE(pCMapFile);
}
}
return(TRUE);
}
BOOLEAN
BuildUV2CIDMap(
PBYTE pCMapFile,
PCMAP pCMap
)
/*++
Routine Description:
Given a memory mapped file ptr to a Postscript CMap, create a CMAP
struture which contains char run information.
Arguments:
pCMapFile - Pointer to a memory mapped CMap file.
pCMap - Pointer to pre allocated memory large enough to contain the CMap.
Return Value:
TRUE => success.
FALSE => error.
--*/
{
ULONG i, cRuns, cRanges;
USHORT chRunStrt, chRunEnd;
PBYTE pToken;
//
// Process the CMap to determine the number of CID runs
// and the number of chars in this char collection.
//
cRuns = cRanges = 0;
for (; (pCMapFile = FindStringToken(pCMapFile, CID_RANGE_TOK)) != NULL; )
{
GET_NUM_CID_RANGES(pCMapFile, cRanges);
//
// Skip to first range.
//
NEXT_LINE(pCMapFile);
for (i = 0; i < cRanges; i++)
{
//
// Retrieve the start and stop codes.
//
PARSE_TOKEN(pCMapFile, pToken);
//
// Get begin and end range codes.
//
if (!AsciiToHex(pToken, &chRunStrt))
{
return(FALSE);
}
if (!AsciiToHex(pCMapFile, &chRunEnd))
{
return(FALSE);
}
pCMap->CMapRange[cRuns + i].ChCodeStrt = chRunStrt;
pCMap->CMapRange[cRuns + i].cChars = chRunEnd - chRunStrt + 1;
//
// Get CID.
//
PARSE_TOKEN(pCMapFile, pToken);
pCMap->CMapRange[cRuns + i].CIDStrt = atol(pCMapFile);
NEXT_LINE(pCMapFile);
}
cRuns += cRanges;
}
pCMap->cRuns = cRuns;
return(TRUE);
}
BOOLEAN
NumUV2CCRuns(
PBYTE pFile,
PULONG pcRuns,
PULONG pcChars
)
/*++
Routine Description:
Given a memory mapped file ptr to a Unicode to CharCode mapping,
determine the number of runs and total number of chars.
Arguments:
pFile - Pointer to a memory mapped file.
pcRuns - Pointer to a ULONG which will contain the number of runs.
pcChars - Pointer to a ULONG which will contain the number of chars.
Return Value:
TRUE => success
FALSE => error
--*/
{
PBYTE pToken;
USHORT lastUnicode, lastCharCode;
USHORT currentUnicode, currentCharCode;
ULONG numChars, numRuns;
*pcRuns = *pcChars = 0;
numChars = numRuns = 0;
lastUnicode = lastCharCode = 0;
currentUnicode = currentCharCode = 0;
while (TRUE)
{
PARSE_TOKEN(pFile, pToken);
if (StrCmp(pToken, "EOF") != 0)
{
if (!AsciiToHex(pToken, &currentUnicode))
{
return(FALSE);
}
PARSE_TOKEN(pFile, pToken);
if (StrCmp(pToken, "EOF") != 0)
{
if (!AsciiToHex(pToken, &currentCharCode))
{
return(FALSE);
}
}
else
return(FALSE);
(*pcChars)++;
}
else
return(TRUE);
if ((currentUnicode > (lastUnicode + 1)) ||
(currentCharCode != (lastCharCode + 1)))
{
(*pcRuns)++;
}
lastUnicode = currentUnicode;
lastCharCode = currentCharCode;
}
}
BOOLEAN
BuildUV2CCMap(
PBYTE pFile,
PCMAP pCMap
)
/*++
Routine Description:
Given a memory mapped file ptr to a Unicode to CharCode mapping,
create a CMAP struture which contains char run information.
Arguments:
pFile - Pointer to a memory mapped file.
pCMap - Pointer to pre allocated memory large enough to contain the CMAP.
Return Value:
TRUE => success.
FALSE => error.
--*/
{
PBYTE pToken;
USHORT startUnicode, startCharCode;
USHORT lastUnicode, lastCharCode;
USHORT currentUnicode, currentCharCode;
ULONG cRuns;
BOOL done = FALSE;
startUnicode = startCharCode = 0;
lastUnicode = lastCharCode = 0;
currentUnicode = currentCharCode = 0;
cRuns = 0;
while (!done)
{
PARSE_TOKEN(pFile, pToken);
if (StrCmp(pToken, "EOF") != 0)
{
if (!AsciiToHex(pToken, &currentUnicode))
{
return(FALSE);
}
PARSE_TOKEN(pFile, pToken);
if (StrCmp(pToken, "EOF") != 0)
{
if (!AsciiToHex(pToken, &currentCharCode))
{
return(FALSE);
}
}
else
return(FALSE);
}
else
done = TRUE;
if ((currentUnicode > (lastUnicode + 1)) ||
(currentCharCode != (lastCharCode + 1)) ||
(done))
{
if (startUnicode > 0)
{
pCMap->CMapRange[cRuns].ChCodeStrt = startUnicode;
pCMap->CMapRange[cRuns].cChars = lastUnicode - startUnicode + 1;
pCMap->CMapRange[cRuns].CIDStrt = startCharCode;
cRuns++;
}
startUnicode = currentUnicode;
startCharCode = currentCharCode;
}
lastUnicode = currentUnicode;
lastCharCode = currentCharCode;
}
pCMap->cRuns = cRuns;
return(TRUE);
}
int __cdecl
CmpCMapRunsCID(
const VOID *p1,
const VOID *p2
)
/*++
Routine Description:
Compares the starting CID of two CMAPRANGE structs.
Arguments:
p1, p2 - CMAPRANGEs to compare.
Return Value:
-1 => p1 < p2
1 => p1 > p2
0 => p1 = p2
--*/
{
PCMAPRANGE ptr1 = (PCMAPRANGE) p1, ptr2 = (PCMAPRANGE) p2;
//
// Compare starting CIDs of the ranges.
//
if (ptr1->CIDStrt > ptr2->CIDStrt)
return(1);
else if (ptr1->CIDStrt < ptr2->CIDStrt)
return(-1);
else
return(0);
}
int __cdecl
CmpCMapRunsChCode(
const VOID *p1,
const VOID *p2
)
/*++
Routine Description:
Compares the starting Char Code of two CMAPRANGE structs.
Arguments:
p1, p2 - CMAPRANGEs to compare.
Return Value:
-1 => p1 < p2
1 => p1 > p2
0 => p1 = p2
--*/
{
PCMAPRANGE ptr1 = (PCMAPRANGE) p1, ptr2 = (PCMAPRANGE) p2;
//
// Compare starting CIDs of the ranges.
//
if (ptr1->ChCodeStrt < ptr2->ChCodeStrt)
return(-1);
else if (ptr1->ChCodeStrt > ptr2->ChCodeStrt)
return(1);
else
return(0);
}
int __cdecl
FindChCodeRun(
const VOID *p1,
const VOID *p2
)
/*++
Routine Description:
Determines if a Charcode falls within a particular CMap run.
Arguments:
p1 - CID
p2 - PCMAPRANGE to check
Return Value:
-1 => p1 < p2
1 => p1 > p2
0 => p1 = p2
--*/
{
PULONG ptr1 = (PULONG) p1;
PCMAPRANGE ptr2 = (PCMAPRANGE) p2;
//
// Determine if CID is in the current range.
//
if (*ptr1 < ptr2->ChCodeStrt)
return(-1);
else if (*ptr1 >= (ULONG) ptr2->ChCodeStrt + ptr2->cChars)
return(1);
else
return(0);
}
int __cdecl
FindCIDRun(
const VOID *p1,
const VOID *p2
)
/*++
Routine Description:
Determines if a CID falls within a particular CMap run.
Arguments:
p1 - CID
p2 - PCMAPRANGE to check
Return Value:
-1 => p1 < p2
1 => p1 > p2
0 => p1 = p2
--*/
{
PULONG ptr1 = (PULONG) p1;
PCMAPRANGE ptr2 = (PCMAPRANGE) p2;
//
// Determine if CID is in the current range.
//
if (*ptr1 < ptr2->CIDStrt)
return(-1);
else if (*ptr1 >= ptr2->CIDStrt + ptr2->cChars)
return(1);
else
return(0);
}
CHSETSUPPORT
IsCJKFont(
PBYTE pAFM
)
/*++
Routine Description:
Determine if a font is a CJK (Far Eastern) font.
Arguments:
pAFM - ptr to memory mapped AFM file
Return Value:
0 - Font not CJK
Otherwise, font is CJK, and return value is the Win Codepage value
--*/
{
PBYTE pToken;
USHORT i;
//
// Search for CharacterSet token.
//
pToken = pAFMCharacterSetString;
if (pToken == NULL)
{
//
// We can't determine if this font is CJK, so assume it isn't.
//
return 0;
}
//
// Search for CharSet (actually Adobe Char Collection) name in CJK table.
//
for (i = 0; i < CjkColTbl.usNumEntries; i++)
{
if (!StrCmp(pToken, (PBYTE) (((PKEY) (CjkColTbl.pTbl))[i].pName)))
{
return(CSUP(((PKEY) (CjkColTbl.pTbl))[i].usValue));
}
}
//
// Not a recognized CJK font.
//
return 0;
}
BOOLEAN
IsVGlyphSet(
PGLYPHSETDATA pGlyphSetData
)
/*++
Routine Description:
Determine if a Glyphset is a CJK V variant. Should ONLY be used with
CJK Glyphsets, otherwise result could be unpredictable!
Arguments:
pGlyphSetData - ptr to GLYPHSETDATA
Return Value:
TRUE - this is a V variant
FALSE - not a V variant
--*/
{
PBYTE pName;
pName = (PBYTE) MK_PTR(pGlyphSetData, dwGlyphSetNameOffset);
return((pName[strlen(pName) - 1] == 'V'));
}
BOOLEAN
IsCIDFont(
PBYTE pAFM
)
/*++
Routine Description:
Determine if a font is a CID font.
Arguments:
pAFM - ptr to memory mapped AFM file
Return Value:
0 - Font not clone.
Otherwise, font is a CID font, and return value non-zero.
--*/
{
PBYTE pToken;
if (pToken = FindAFMToken(pAFM, PS_CIDFONT_TOK))
{
if (!StrCmp(pToken, "true"))
return TRUE;
}
return FALSE;
}