|
|
/*++
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, ¤tUnicode)) { return(FALSE); }
PARSE_TOKEN(pFile, pToken); if (StrCmp(pToken, "EOF") != 0) { if (!AsciiToHex(pToken, ¤tCharCode)) { 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, ¤tUnicode)) { return(FALSE); }
PARSE_TOKEN(pFile, pToken); if (StrCmp(pToken, "EOF") != 0) { if (!AsciiToHex(pToken, ¤tCharCode)) { 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; }
|