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

  1. /*++
  2. Copyright (c) 1996 Adobe Systems Incorporated
  3. Copyright (c) 1996 Microsoft Corporation
  4. Module Name:
  5. cjkfonts.c
  6. Abstract:
  7. Convert CJK AFMs to NTMs.
  8. Environment:
  9. Windows NT PostScript driver: makentf utility.
  10. Revision History:
  11. 02/10/98 -ksuzuki-
  12. Added OCF font support using 83pv font; did code cleanup, especially
  13. of the CreateCJKGlyphSets function.
  14. 01/13/96 -rkiesler-
  15. Wrote it.
  16. -*/
  17. #include "lib.h"
  18. #include "ppd.h"
  19. #include "pslib.h"
  20. #include "psglyph.h"
  21. #include "afm2ntm.h"
  22. #include "cjkfonts.h"
  23. #include "winfont.h"
  24. extern BOOL bVerbose;
  25. ULONG
  26. CreateCJKGlyphSets(
  27. PBYTE *pUV2CCMaps,
  28. PBYTE *pUV2CIDMaps,
  29. PGLYPHSETDATA *pGlyphSets,
  30. PWINCODEPAGE pWinCodePage,
  31. PULONG *pUniPsTbl
  32. )
  33. /*++
  34. Routine Description:
  35. Given memory mapped file ptrs to H and V Unicode to CharCode map files
  36. and H and V Unicode to CID map files, create 2 GLYPHSETDATA structures
  37. which represent H and V variants of the character collection. Create
  38. ptrs to 2 tables which map glyph indices to CIDs for each variant.
  39. Arguments:
  40. pUV2CCMaps - Pointer to two memory mapped map files. These map Unicode
  41. value to corresponding character code. pUV2CCMaps[0] and pUV2CCMaps[1]
  42. for H and V respectively.
  43. pUV2CIDMaps - Pointer to two memory mapped map files. These Unicode to
  44. corresponding CID. pUV2CIDMaps[0] and pUV2CIDMaps[1] for H and V
  45. respectively.
  46. pGlyphSets - two position array of GLYPHSETDATA pointers which upon
  47. successful completion contain the addresses of the newly allocated
  48. GLYPHSETDATA structs representing the H and V variants of the char
  49. collection.
  50. pWinCodePage - Pts to a WINCODEPAGE struct which provides Windows
  51. specific info about this charset.
  52. pUniPsTbl - two position array of ULONG ptrs which each pts to a table
  53. which maps 0-based Glyph Indices of chars in the GLYPHRUNS of the
  54. GLYPHSETDATA for this char collection to CIDs.
  55. Return Value:
  56. TRUE => success.
  57. FALSE => error.
  58. --*/
  59. {
  60. PBYTE pToken, pGlyphSetName;
  61. ULONG cChars, cRuns, cRanges, curCID;
  62. USHORT cCharRun;
  63. PGLYPHRUN pGlyphRuns;
  64. PCMAP pUv2CcMap[NUM_VARIANTS];
  65. PCMAP pUv2CidMap[NUM_VARIANTS];
  66. ULONG c, i, uv;
  67. PVOID pMapTbl;
  68. PCMAPRANGE pCMapRange;
  69. PCMAP pSrchCMap;
  70. ULONG cGlyphSetBytes[NUM_VARIANTS], cSizeBytes[NUM_VARIANTS];
  71. BOOLEAN bFound, bInRun;
  72. USHORT wcRunStrt;
  73. DWORD dwGSNameSize, dwCodePageInfoSize, dwGlyphRunSize, dwCPIGSNameSize;
  74. DWORD dwEncodingNameOffset;
  75. PCODEPAGEINFO pCodePageInfo;
  76. BOOL bSingleCodePage;
  77. if (bVerbose) printf("%%%%[Begin Create CJK glyphset]%%%%\n\n");
  78. //////////////////////////////////////////////////////////////////////////
  79. //
  80. // Create the local Unicode->CharCode and Unicode->CID Maps sorted in
  81. // starting Unicode order.
  82. //
  83. //////////////////////////////////////////////////////////////////////////
  84. //
  85. // Get pointer to, and determine size of, the name strings for each variant.
  86. //
  87. for (i = 0; i < NUM_VARIANTS; i++)
  88. {
  89. //
  90. // Process the Unicode->CharCode map to determine the number of its
  91. // chars and runs.
  92. //
  93. if (NumUV2CCRuns(pUV2CCMaps[i], &cRuns, &cChars) == FALSE)
  94. {
  95. return(FALSE);
  96. }
  97. //
  98. // Alloc memory for create local CMap structs needed to build
  99. // GLYPHSETs.
  100. //
  101. pUv2CcMap[i] = (PCMAP)MemAllocZ(sizeof(CMAP) + sizeof(CMAPRANGE) * (cRuns - 1));
  102. if (pUv2CcMap[i] == NULL)
  103. {
  104. ERR(("makentf - CreateCJKGlyphSets: MemAllocZ\n"));
  105. return(FALSE);
  106. }
  107. pUv2CcMap[i]->cChars = cChars;
  108. if (BuildUV2CCMap(pUV2CCMaps[i], pUv2CcMap[i]) == FALSE)
  109. {
  110. return(FALSE);
  111. }
  112. //
  113. // Sort the CMap ranges in starting Unicode order.
  114. //
  115. qsort(pUv2CcMap[i]->CMapRange,
  116. (size_t)pUv2CcMap[i]->cRuns,
  117. (size_t)sizeof(CMAPRANGE),
  118. CmpCMapRunsChCode);
  119. //
  120. // Process the Unicode->CID map to determine the number of its
  121. // chars and runs.
  122. //
  123. if (NumUV2CIDRuns(pUV2CIDMaps[i], &cRuns, &cChars) == FALSE)
  124. {
  125. return(FALSE);
  126. }
  127. pUv2CidMap[i] = (PCMAP)MemAllocZ(sizeof(CMAP) + sizeof(CMAPRANGE) * (cRuns - 1));
  128. if (pUv2CidMap[i] == NULL)
  129. {
  130. ERR(("makentf - CreateCJKGlyphSets: MemAllocZ\n"));
  131. return(FALSE);
  132. }
  133. pUv2CidMap[i]->cChars = cChars;
  134. if (BuildUV2CIDMap(pUV2CIDMaps[i], pUv2CidMap[i]) == FALSE)
  135. {
  136. return(FALSE);
  137. }
  138. //
  139. // Sort CMap Ranges in Starting char code order.
  140. //
  141. qsort(pUv2CidMap[i]->CMapRange,
  142. (size_t)pUv2CidMap[i]->cRuns,
  143. (size_t)sizeof(CMAPRANGE),
  144. CmpCMapRunsChCode);
  145. }
  146. //
  147. // CJK fonts never have multiple codepages, but, we figure it out anyway
  148. // just in case.
  149. //
  150. bSingleCodePage = (pWinCodePage->usNumBaseCsets == 1) ? TRUE : FALSE;
  151. //////////////////////////////////////////////////////////////////////////
  152. //
  153. // Create H GLYPHSETDATA
  154. //
  155. //////////////////////////////////////////////////////////////////////////
  156. //
  157. // Count chars and runs in H CMaps.
  158. //
  159. // Look up all Unicode points in the H Unicode->CID map and the H Unicode->
  160. // CharCode map to determine number of GLYPHRUNs required for the
  161. // GLYPHSETDATA we are about to create.
  162. //
  163. cChars = cRuns = 0;
  164. bInRun = bFound = FALSE;
  165. for (uv = 0; uv < NUM_UNICODE_CHARS; uv++)
  166. {
  167. //
  168. // Search for the Unicode value in H Unicode->CharCode map.
  169. //
  170. pCMapRange = (PCMAPRANGE)bsearch(&uv,
  171. pUv2CidMap[H_CMAP]->CMapRange,
  172. pUv2CidMap[H_CMAP]->cRuns,
  173. sizeof(CMAPRANGE),
  174. FindChCodeRun);
  175. bFound = (pCMapRange != NULL);
  176. if (bFound)
  177. {
  178. //
  179. // Found this unicode value in H Unicode->CID map. Determine if it
  180. // maps to a CharCode in H Unicode->CharCode map.
  181. //
  182. bFound = (bsearch(&uv,
  183. pUv2CcMap[H_CMAP]->CMapRange,
  184. pUv2CcMap[H_CMAP]->cRuns,
  185. sizeof(CMAPRANGE),
  186. FindChCodeRun) != NULL);
  187. if (bFound)
  188. {
  189. cChars++;
  190. }
  191. }
  192. //
  193. // Determine if this is a new run.
  194. //
  195. bInRun = bFound && bInRun;
  196. if (bFound && !bInRun)
  197. {
  198. cRuns++;
  199. bInRun = TRUE;
  200. }
  201. }
  202. //
  203. // Compute amount of memory required for H GLYPHSET.
  204. // Note to account for the H/V char appended to the GlyphSet name.
  205. //
  206. dwGSNameSize = ALIGN4(strlen(pWinCodePage->pszCPname) + 2);
  207. dwCodePageInfoSize = ALIGN4(pWinCodePage->usNumBaseCsets * sizeof(CODEPAGEINFO));
  208. dwGlyphRunSize = ALIGN4(cRuns * sizeof(GLYPHRUN));
  209. cGlyphSetBytes[H_CMAP] = ALIGN4(sizeof(GLYPHSETDATA));
  210. cGlyphSetBytes[H_CMAP] += dwGSNameSize;
  211. cGlyphSetBytes[H_CMAP] += dwCodePageInfoSize;
  212. cGlyphSetBytes[H_CMAP] += dwGlyphRunSize;
  213. //
  214. // Account for the size of the mapping table.
  215. //
  216. cGlyphSetBytes[H_CMAP] += bSingleCodePage ? ALIGN4((cChars * sizeof (WORD))) : (cChars * sizeof (DWORD));
  217. //
  218. // Account for size of CODEPAGE name strings found in CODEPAGEINFO
  219. // struct(s).
  220. //
  221. for (dwCPIGSNameSize = 0, i = 0; i < pWinCodePage->usNumBaseCsets; i++)
  222. {
  223. dwCPIGSNameSize += ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1);
  224. }
  225. cGlyphSetBytes[H_CMAP] += dwCPIGSNameSize;
  226. //
  227. // Alloc memory for H GLYPHSET, Unicode->CID mapping table.
  228. //
  229. pGlyphSets[H_CMAP] = (PGLYPHSETDATA)MemAllocZ(cGlyphSetBytes[H_CMAP]);
  230. if (pGlyphSets[H_CMAP] == NULL)
  231. {
  232. ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
  233. return(FALSE);
  234. }
  235. pUniPsTbl[H_CMAP] = (PULONG)MemAllocZ(cChars * sizeof(ULONG));
  236. if (pUniPsTbl[H_CMAP] == NULL)
  237. {
  238. ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
  239. return(FALSE);
  240. }
  241. //
  242. // Init GLYPHSETDATA for H.
  243. //
  244. pGlyphSets[H_CMAP]->dwSize = cGlyphSetBytes[H_CMAP];
  245. pGlyphSets[H_CMAP]->dwVersion = GLYPHSETDATA_VERSION;
  246. pGlyphSets[H_CMAP]->dwFlags = 0;
  247. pGlyphSets[H_CMAP]->dwGlyphSetNameOffset = ALIGN4(sizeof(GLYPHSETDATA));
  248. pGlyphSets[H_CMAP]->dwGlyphCount = cChars;
  249. pGlyphSets[H_CMAP]->dwCodePageCount = pWinCodePage->usNumBaseCsets;
  250. pGlyphSets[H_CMAP]->dwCodePageOffset = pGlyphSets[H_CMAP]->dwGlyphSetNameOffset + dwGSNameSize;
  251. pGlyphSets[H_CMAP]->dwRunCount = cRuns;
  252. pGlyphSets[H_CMAP]->dwRunOffset = pGlyphSets[H_CMAP]->dwCodePageOffset + dwCodePageInfoSize + dwCPIGSNameSize;
  253. pGlyphSets[H_CMAP]->dwMappingTableOffset = pGlyphSets[H_CMAP]->dwRunOffset + dwGlyphRunSize;
  254. //
  255. // Set the mapping table type flag to dwFlags field.
  256. //
  257. pGlyphSets[H_CMAP]->dwFlags |= bSingleCodePage ? GSD_MTT_WCC : GSD_MTT_DWCPCC;
  258. //
  259. // Store GlyphSet name
  260. //
  261. pGlyphSetName = (PBYTE)MK_PTR(pGlyphSets[H_CMAP], dwGlyphSetNameOffset);
  262. StringCchCopyA(pGlyphSetName, dwGSNameSize, pWinCodePage->pszCPname);
  263. pGlyphSetName[strlen(pWinCodePage->pszCPname)] = 'H';
  264. pGlyphSetName[strlen(pWinCodePage->pszCPname) + 1] = '\0';
  265. //
  266. // Initialize a CODEPAGEINFO struct for each base charset supported
  267. // by this font.
  268. //
  269. pCodePageInfo = (PCODEPAGEINFO)MK_PTR(pGlyphSets[H_CMAP], dwCodePageOffset);
  270. dwEncodingNameOffset = dwCodePageInfoSize;
  271. for (i = 0; i < pWinCodePage->usNumBaseCsets; i++, pCodePageInfo++)
  272. {
  273. //
  274. // Save CODEPAGEINFO name, id. We don't use PS encoding vectors.
  275. //
  276. pCodePageInfo->dwCodePage = aPStoCP[pWinCodePage->pCsetList[i]].usACP;
  277. pCodePageInfo->dwWinCharset = (DWORD)aPStoCP[pWinCodePage->pCsetList[i]].jWinCharset;
  278. pCodePageInfo->dwEncodingNameOffset = dwEncodingNameOffset;
  279. pCodePageInfo->dwEncodingVectorDataSize = 0;
  280. pCodePageInfo->dwEncodingVectorDataOffset = 0;
  281. //
  282. // Copy codepage name string to end of array of CODEPAGEINFOs.
  283. //
  284. StringCchCopyA((PBYTE)MK_PTR(pCodePageInfo, dwEncodingNameOffset),
  285. ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1),
  286. aPStoCP[pWinCodePage->pCsetList[i]].pGSName);
  287. //
  288. // Adjust the offset to the CodePage name for the next CODEPAGEINFO structure.
  289. //
  290. dwEncodingNameOffset -= ALIGN4(sizeof (CODEPAGEINFO));
  291. dwEncodingNameOffset += ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1);
  292. }
  293. //
  294. // Process H Unicode->CID/CharCode maps to determine the number of its
  295. // chars and runs.
  296. //
  297. cRuns = 0;
  298. cCharRun = 0;
  299. bInRun = FALSE;
  300. pGlyphRuns = GSD_GET_GLYPHRUN(pGlyphSets[H_CMAP]);
  301. pMapTbl = GSD_GET_MAPPINGTABLE(pGlyphSets[H_CMAP]);
  302. for (uv = c = 0; (uv < NUM_UNICODE_CHARS) && (c < cChars); uv++)
  303. {
  304. pCMapRange = bsearch(&uv,
  305. pUv2CidMap[H_CMAP]->CMapRange,
  306. pUv2CidMap[H_CMAP]->cRuns,
  307. sizeof(CMAPRANGE),
  308. FindChCodeRun);
  309. bFound = (pCMapRange != NULL);
  310. if (bFound)
  311. {
  312. curCID = pCMapRange->CIDStrt + uv - pCMapRange->ChCodeStrt;
  313. pCMapRange = bsearch(&uv,
  314. pUv2CcMap[H_CMAP]->CMapRange,
  315. pUv2CcMap[H_CMAP]->cRuns,
  316. sizeof(CMAPRANGE),
  317. FindChCodeRun);
  318. bFound = (pCMapRange != NULL);
  319. if (bFound)
  320. {
  321. //
  322. // Found this Unicode value in Unicode->CharCode map. Store in
  323. // mapping table. Note that CJK fonts only support 1 charset
  324. // per font.
  325. //
  326. pUniPsTbl[H_CMAP][c] = curCID;
  327. if (bSingleCodePage)
  328. {
  329. if (pCMapRange != NULL)
  330. ((WORD*)pMapTbl)[c] = (WORD)(pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt));
  331. else
  332. ((WORD*)pMapTbl)[c] = (WORD)uv;
  333. }
  334. else
  335. {
  336. ((DWORD*)pMapTbl)[c] = aPStoCP[pWinCodePage->pCsetList[0]].usACP << 16;
  337. if (pCMapRange != NULL)
  338. {
  339. ((DWORD*)pMapTbl)[c] |= pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt);
  340. }
  341. else
  342. {
  343. ((DWORD*)pMapTbl)[c] |= uv;
  344. }
  345. }
  346. c++;
  347. cCharRun++;
  348. }
  349. }
  350. //
  351. // Determine if this is a new Unicode run.
  352. //
  353. if (bFound && !bInRun)
  354. {
  355. //
  356. // This is the beginning of a new run.
  357. //
  358. bInRun = TRUE;
  359. pGlyphRuns[cRuns].wcLow = (USHORT) (uv & 0xffff);
  360. }
  361. //
  362. // Determine if this is the end of a run.
  363. //
  364. if (bInRun && (!bFound || uv == NUM_UNICODE_CHARS || c == cChars))
  365. {
  366. //
  367. // This is the end of a run.
  368. //
  369. bInRun = FALSE;
  370. pGlyphRuns[cRuns].wGlyphCount = cCharRun;
  371. cRuns++;
  372. cCharRun = 0;
  373. }
  374. }
  375. //////////////////////////////////////////////////////////////////////////
  376. //
  377. // Create V GLYPHSETDATA
  378. //
  379. //////////////////////////////////////////////////////////////////////////
  380. //
  381. // Count chars and runs in V maps.
  382. //
  383. // For the V GLYPHSETDATA, if a Unicode value is not found in V Unicode->
  384. // CID map, we will then need to check H Unicode->CID map.
  385. //
  386. cChars = cRuns = 0;
  387. bInRun = bFound = FALSE;
  388. for (uv = 0; uv < NUM_UNICODE_CHARS; uv++)
  389. {
  390. //
  391. // Search for the Unicode value in V, and then H Unicode->CID maps if
  392. // not found.
  393. //
  394. pCMapRange = bsearch(&uv,
  395. pUv2CidMap[V_CMAP]->CMapRange,
  396. pUv2CidMap[V_CMAP]->cRuns,
  397. sizeof(CMAPRANGE),
  398. FindChCodeRun);
  399. bFound = (pCMapRange != NULL);
  400. if (bFound == FALSE)
  401. {
  402. pCMapRange = bsearch(&uv,
  403. pUv2CidMap[H_CMAP]->CMapRange,
  404. pUv2CidMap[H_CMAP]->cRuns,
  405. sizeof(CMAPRANGE),
  406. FindChCodeRun);
  407. bFound = (pCMapRange != NULL);
  408. }
  409. if (bFound)
  410. {
  411. //
  412. // Found this unicode value. Determine if it maps to a CharCode in
  413. // H or V Unicode->CharCode map.
  414. //
  415. pCMapRange = bsearch(&uv,
  416. pUv2CcMap[V_CMAP]->CMapRange,
  417. pUv2CcMap[V_CMAP]->cRuns,
  418. sizeof(CMAPRANGE),
  419. FindChCodeRun);
  420. bFound = (pCMapRange != NULL);
  421. if (bFound == FALSE)
  422. {
  423. pCMapRange = bsearch(&uv,
  424. pUv2CcMap[H_CMAP]->CMapRange,
  425. pUv2CcMap[H_CMAP]->cRuns,
  426. sizeof(CMAPRANGE),
  427. FindChCodeRun);
  428. bFound = (pCMapRange != NULL);
  429. }
  430. if (bFound)
  431. {
  432. cChars++;
  433. }
  434. }
  435. //
  436. // Determine if this is a new run.
  437. //
  438. bInRun = bFound && bInRun;
  439. if (bFound && !bInRun)
  440. {
  441. cRuns++;
  442. bInRun = TRUE;
  443. }
  444. }
  445. //
  446. // Compute amount of memory required for V GLYPHSET.
  447. //
  448. dwGSNameSize = ALIGN4(strlen(pWinCodePage->pszCPname) + 2);
  449. dwCodePageInfoSize = ALIGN4(pWinCodePage->usNumBaseCsets * sizeof(CODEPAGEINFO));
  450. dwGlyphRunSize = ALIGN4(cRuns * sizeof(GLYPHRUN));
  451. cGlyphSetBytes[V_CMAP] = ALIGN4(sizeof(GLYPHSETDATA));
  452. cGlyphSetBytes[V_CMAP] += dwGSNameSize;
  453. cGlyphSetBytes[V_CMAP] += dwCodePageInfoSize;
  454. cGlyphSetBytes[V_CMAP] += dwGlyphRunSize;
  455. //
  456. // Account for the size of the mapping table.
  457. //
  458. cGlyphSetBytes[V_CMAP] += bSingleCodePage ? ALIGN4((cChars * sizeof (WORD))) : (cChars * sizeof (DWORD));
  459. //
  460. // Account for size of CODEPAGE name strings found in CODEPAGEINFO
  461. // struct(s).
  462. //
  463. for (dwCPIGSNameSize = 0, i = 0; i < pWinCodePage->usNumBaseCsets; i++)
  464. {
  465. dwCPIGSNameSize += ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1);
  466. }
  467. cGlyphSetBytes[V_CMAP] += dwCPIGSNameSize;
  468. //
  469. // Alloc memory for V GLYPHSET, Unicode->CID mapping table.
  470. //
  471. pGlyphSets[V_CMAP] = (PGLYPHSETDATA)MemAllocZ(cGlyphSetBytes[V_CMAP]);
  472. if (pGlyphSets[V_CMAP] == NULL)
  473. {
  474. ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
  475. return(FALSE);
  476. }
  477. pUniPsTbl[V_CMAP] = (PULONG)MemAllocZ(cChars * sizeof(ULONG));
  478. if (pUniPsTbl[V_CMAP] == NULL)
  479. {
  480. ERR(("makentf - CreateCJKGlyphSets: malloc\n"));
  481. return(FALSE);
  482. }
  483. //
  484. // Init GLYPHSETDATA for V.
  485. //
  486. pGlyphSets[V_CMAP]->dwSize = cGlyphSetBytes[V_CMAP];
  487. pGlyphSets[V_CMAP]->dwVersion = GLYPHSETDATA_VERSION;
  488. pGlyphSets[V_CMAP]->dwFlags = 0;
  489. pGlyphSets[V_CMAP]->dwGlyphSetNameOffset = ALIGN4(sizeof(GLYPHSETDATA));
  490. pGlyphSets[V_CMAP]->dwGlyphCount = cChars;
  491. pGlyphSets[V_CMAP]->dwCodePageCount = pWinCodePage->usNumBaseCsets;
  492. pGlyphSets[V_CMAP]->dwCodePageOffset = pGlyphSets[V_CMAP]->dwGlyphSetNameOffset + dwGSNameSize;
  493. pGlyphSets[V_CMAP]->dwRunCount = cRuns;
  494. pGlyphSets[V_CMAP]->dwRunOffset = pGlyphSets[V_CMAP]->dwCodePageOffset + dwCodePageInfoSize + dwCPIGSNameSize;
  495. pGlyphSets[V_CMAP]->dwMappingTableOffset = pGlyphSets[V_CMAP]->dwRunOffset + dwGlyphRunSize;
  496. //
  497. // Set the mapping table type flag to dwFlags field.
  498. //
  499. pGlyphSets[V_CMAP]->dwFlags |= bSingleCodePage ? GSD_MTT_WCC : GSD_MTT_DWCPCC;
  500. //
  501. // Store GlyphSet name
  502. //
  503. pGlyphSetName = (PBYTE)MK_PTR(pGlyphSets[V_CMAP], dwGlyphSetNameOffset);
  504. StringCchCopyA(pGlyphSetName, dwGSNameSize, pWinCodePage->pszCPname);
  505. pGlyphSetName[strlen(pWinCodePage->pszCPname)] = 'V';
  506. pGlyphSetName[strlen(pWinCodePage->pszCPname) + 1] = '\0';
  507. //
  508. // Initialize a CODEPAGEINFO struct for each base charset supported
  509. // by this font.
  510. //
  511. pCodePageInfo = (PCODEPAGEINFO) MK_PTR(pGlyphSets[V_CMAP], dwCodePageOffset);
  512. dwEncodingNameOffset = dwCodePageInfoSize;
  513. for (i = 0; i < pWinCodePage->usNumBaseCsets; i++, pCodePageInfo++)
  514. {
  515. //
  516. // Save CODEPAGEINFO name, id. We don't use PS encoding vectors.
  517. //
  518. pCodePageInfo->dwCodePage = aPStoCP[pWinCodePage->pCsetList[i]].usACP;
  519. pCodePageInfo->dwWinCharset = (DWORD)aPStoCP[pWinCodePage->pCsetList[i]].jWinCharset;
  520. pCodePageInfo->dwEncodingNameOffset = dwEncodingNameOffset;
  521. pCodePageInfo->dwEncodingVectorDataSize = 0;
  522. pCodePageInfo->dwEncodingVectorDataOffset = 0;
  523. //
  524. // Copy codepage name string to end of array of CODEPAGEINFOs.
  525. //
  526. StringCchCopyA((PBYTE)MK_PTR(pCodePageInfo, dwEncodingNameOffset),
  527. ALIGN4(strlen(aPStoCP[pWinCodePage->pCsetList[i]].pGSName) + 1),
  528. aPStoCP[pWinCodePage->pCsetList[i]].pGSName);
  529. //
  530. // Adjust the offset to the CodePage name for the next CODEPAGEINFO structure.
  531. //
  532. dwEncodingNameOffset -= sizeof(CODEPAGEINFO);
  533. dwEncodingNameOffset += ALIGN4(strlen((PSZ)MK_PTR(pCodePageInfo, dwEncodingNameOffset)) + 1);
  534. }
  535. //
  536. // Create V Glyphset by merging V and H Maps.
  537. //
  538. //
  539. // Determine number of runs, chars in the Glyphset created when V and H
  540. // Maps are merged.
  541. //
  542. cRuns = 0;
  543. cCharRun = 0;
  544. bInRun = bFound = FALSE;
  545. pGlyphRuns = GSD_GET_GLYPHRUN(pGlyphSets[V_CMAP]);
  546. pMapTbl = GSD_GET_MAPPINGTABLE(pGlyphSets[V_CMAP]);
  547. for (uv = c = 0; (uv < NUM_UNICODE_CHARS) && (c < cChars); uv++)
  548. {
  549. pCMapRange = bsearch(&uv,
  550. pUv2CidMap[V_CMAP]->CMapRange,
  551. pUv2CidMap[V_CMAP]->cRuns,
  552. sizeof(CMAPRANGE),
  553. FindChCodeRun);
  554. bFound = (pCMapRange != NULL);
  555. if (bFound == FALSE)
  556. {
  557. pCMapRange = bsearch(&uv,
  558. pUv2CidMap[H_CMAP]->CMapRange,
  559. pUv2CidMap[H_CMAP]->cRuns,
  560. sizeof(CMAPRANGE),
  561. FindChCodeRun);
  562. bFound = (pCMapRange != NULL);
  563. }
  564. //
  565. // Found this Unicode value. Determine if it maps to a CharCode in H
  566. // or V Unicode->CC map.
  567. //
  568. if (bFound)
  569. {
  570. curCID = pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt);
  571. pCMapRange = bsearch(&uv,
  572. pUv2CcMap[V_CMAP]->CMapRange,
  573. pUv2CcMap[V_CMAP]->cRuns,
  574. sizeof(CMAPRANGE),
  575. FindChCodeRun);
  576. bFound = (pCMapRange != NULL);
  577. if (bFound == FALSE)
  578. {
  579. pCMapRange = bsearch(&uv,
  580. pUv2CcMap[H_CMAP]->CMapRange,
  581. pUv2CcMap[H_CMAP]->cRuns,
  582. sizeof(CMAPRANGE),
  583. FindChCodeRun);
  584. bFound = (pCMapRange != NULL);
  585. }
  586. if (bFound)
  587. {
  588. //
  589. // Found this Unicode value in Unicode->CharCode map. Store in
  590. // mapping table. Note that CJK fonts only support 1 charset
  591. // per font.
  592. //
  593. pUniPsTbl[V_CMAP][c] = curCID;
  594. if (bSingleCodePage)
  595. {
  596. if (pCMapRange != NULL)
  597. ((WORD*)pMapTbl)[c] = (WORD)(pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt));
  598. else
  599. ((WORD*)pMapTbl)[c] = (WORD)uv;
  600. }
  601. else
  602. {
  603. ((DWORD*)pMapTbl)[c] = aPStoCP[pWinCodePage->pCsetList[0]].usACP << 16;
  604. if (pCMapRange != NULL)
  605. {
  606. ((DWORD*)pMapTbl)[c] |= pCMapRange->CIDStrt + (uv - pCMapRange->ChCodeStrt);
  607. }
  608. else
  609. {
  610. ((DWORD*)pMapTbl)[c] |= uv;
  611. }
  612. }
  613. c++;
  614. cCharRun++;
  615. }
  616. }
  617. //
  618. // Determine if this is a new Unicode run.
  619. //
  620. if (bFound && !bInRun)
  621. {
  622. //
  623. // This is the beginning of a new run.
  624. //
  625. bInRun = TRUE;
  626. pGlyphRuns[cRuns].wcLow = (USHORT) (uv & 0xffff);
  627. }
  628. //
  629. // Determine if this is the end of a run.
  630. //
  631. if (bInRun && (!bFound || uv == NUM_UNICODE_CHARS || c == cChars))
  632. {
  633. //
  634. // This is the end of a run.
  635. //
  636. bInRun = FALSE;
  637. pGlyphRuns[cRuns].wGlyphCount = cCharRun;
  638. cRuns++;
  639. cCharRun = 0;
  640. }
  641. }
  642. if (bVerbose)
  643. {
  644. for (i = 0; i < NUM_VARIANTS; i++)
  645. {
  646. printf("GLYPHSETDATA:dwFlags:%08X\n", pGlyphSets[i]->dwFlags);
  647. printf("GLYPHSETDATA:dwGlyphSetNameOffset:%s\n",
  648. (PSZ)MK_PTR(pGlyphSets[i], dwGlyphSetNameOffset));
  649. printf("GLYPHSETDATA:dwGlyphCount:%ld\n", pGlyphSets[i]->dwGlyphCount);
  650. printf("GLYPHSETDATA:dwRunCount:%ld\n", pGlyphSets[i]->dwRunCount);
  651. printf("GLYPHSETDATA:dwCodePageCount:%ld\n", pGlyphSets[i]->dwCodePageCount);
  652. {
  653. DWORD dw;
  654. PCODEPAGEINFO pcpi = (PCODEPAGEINFO)MK_PTR(pGlyphSets[i], dwCodePageOffset);
  655. for (dw = 1; dw <= pGlyphSets[i]->dwCodePageCount; dw++)
  656. {
  657. printf("CODEPAGEINFO#%ld:dwCodePage:%ld\n", dw, pcpi->dwCodePage);
  658. printf("CODEPAGEINFO#%ld:dwWinCharset:%ld\n", dw, pcpi->dwWinCharset);
  659. printf("CODEPAGEINFO#%ld:dwEncodingNameOffset:%s\n",
  660. dw, (PSZ)MK_PTR(pcpi, dwEncodingNameOffset));
  661. pcpi++;
  662. }
  663. }
  664. printf("\n");
  665. }
  666. }
  667. //
  668. // Clean-up: free the local Maps.
  669. //
  670. for (i = 0; i < NUM_VARIANTS; i++)
  671. {
  672. //
  673. // Free temporary data structs.
  674. //
  675. if (pUv2CcMap[i] != NULL)
  676. {
  677. MemFree(pUv2CcMap[i]);
  678. }
  679. if (pUv2CidMap[i] != NULL)
  680. {
  681. MemFree(pUv2CidMap[i]);
  682. }
  683. }
  684. if (bVerbose) printf("%%[End Create CJK glyphset]%%%%\n\n");
  685. return(TRUE);
  686. }
  687. BOOLEAN
  688. NumUV2CIDRuns(
  689. PBYTE pCMapFile,
  690. PULONG pcRuns,
  691. PULONG pcChars
  692. )
  693. /*++
  694. Routine Description:
  695. Given a memory mapped file ptr to a Postscript CMap, determine
  696. the number of CIDRanges (Runs) and total number of chars.
  697. Arguments:
  698. pCMapFile - Pointer to a memory mapped CMap file.
  699. pcRuns - Pointer to a ULONG which will contain the number of runs.
  700. pcChars - Pointer to a ULONG which will contain the number of chars.
  701. Return Value:
  702. TRUE => success
  703. FALSE => error
  704. --*/
  705. {
  706. PBYTE pToken;
  707. ULONG cRanges, i;
  708. USHORT chRunStrt, chRunEnd;
  709. BYTE LineBuffer[25];
  710. USHORT usLineLen;
  711. *pcRuns = *pcChars = 0;
  712. //
  713. // Search for the CID ranges, and determine the number of runs and
  714. // total number of chars in this GLYPHSET.
  715. //
  716. for (; (pCMapFile = FindStringToken(pCMapFile, CID_RANGE_TOK)) != NULL; )
  717. {
  718. GET_NUM_CID_RANGES(pCMapFile, cRanges);
  719. *pcRuns += cRanges;
  720. NEXT_LINE(pCMapFile);
  721. for (i = 0; i < cRanges; i++)
  722. {
  723. PARSE_TOKEN(pCMapFile, pToken);
  724. //
  725. // Get begin and end range codes.
  726. //
  727. if (!AsciiToHex(pToken, &chRunStrt))
  728. {
  729. return(FALSE);
  730. }
  731. if (!AsciiToHex(pCMapFile, &chRunEnd))
  732. {
  733. return(FALSE);
  734. }
  735. //
  736. // Compute size of run.
  737. //
  738. *pcChars += chRunEnd - chRunStrt + 1;
  739. NEXT_LINE(pCMapFile);
  740. }
  741. }
  742. return(TRUE);
  743. }
  744. BOOLEAN
  745. BuildUV2CIDMap(
  746. PBYTE pCMapFile,
  747. PCMAP pCMap
  748. )
  749. /*++
  750. Routine Description:
  751. Given a memory mapped file ptr to a Postscript CMap, create a CMAP
  752. struture which contains char run information.
  753. Arguments:
  754. pCMapFile - Pointer to a memory mapped CMap file.
  755. pCMap - Pointer to pre allocated memory large enough to contain the CMap.
  756. Return Value:
  757. TRUE => success.
  758. FALSE => error.
  759. --*/
  760. {
  761. ULONG i, cRuns, cRanges;
  762. USHORT chRunStrt, chRunEnd;
  763. PBYTE pToken;
  764. //
  765. // Process the CMap to determine the number of CID runs
  766. // and the number of chars in this char collection.
  767. //
  768. cRuns = cRanges = 0;
  769. for (; (pCMapFile = FindStringToken(pCMapFile, CID_RANGE_TOK)) != NULL; )
  770. {
  771. GET_NUM_CID_RANGES(pCMapFile, cRanges);
  772. //
  773. // Skip to first range.
  774. //
  775. NEXT_LINE(pCMapFile);
  776. for (i = 0; i < cRanges; i++)
  777. {
  778. //
  779. // Retrieve the start and stop codes.
  780. //
  781. PARSE_TOKEN(pCMapFile, pToken);
  782. //
  783. // Get begin and end range codes.
  784. //
  785. if (!AsciiToHex(pToken, &chRunStrt))
  786. {
  787. return(FALSE);
  788. }
  789. if (!AsciiToHex(pCMapFile, &chRunEnd))
  790. {
  791. return(FALSE);
  792. }
  793. pCMap->CMapRange[cRuns + i].ChCodeStrt = chRunStrt;
  794. pCMap->CMapRange[cRuns + i].cChars = chRunEnd - chRunStrt + 1;
  795. //
  796. // Get CID.
  797. //
  798. PARSE_TOKEN(pCMapFile, pToken);
  799. pCMap->CMapRange[cRuns + i].CIDStrt = atol(pCMapFile);
  800. NEXT_LINE(pCMapFile);
  801. }
  802. cRuns += cRanges;
  803. }
  804. pCMap->cRuns = cRuns;
  805. return(TRUE);
  806. }
  807. BOOLEAN
  808. NumUV2CCRuns(
  809. PBYTE pFile,
  810. PULONG pcRuns,
  811. PULONG pcChars
  812. )
  813. /*++
  814. Routine Description:
  815. Given a memory mapped file ptr to a Unicode to CharCode mapping,
  816. determine the number of runs and total number of chars.
  817. Arguments:
  818. pFile - Pointer to a memory mapped file.
  819. pcRuns - Pointer to a ULONG which will contain the number of runs.
  820. pcChars - Pointer to a ULONG which will contain the number of chars.
  821. Return Value:
  822. TRUE => success
  823. FALSE => error
  824. --*/
  825. {
  826. PBYTE pToken;
  827. USHORT lastUnicode, lastCharCode;
  828. USHORT currentUnicode, currentCharCode;
  829. ULONG numChars, numRuns;
  830. *pcRuns = *pcChars = 0;
  831. numChars = numRuns = 0;
  832. lastUnicode = lastCharCode = 0;
  833. currentUnicode = currentCharCode = 0;
  834. while (TRUE)
  835. {
  836. PARSE_TOKEN(pFile, pToken);
  837. if (StrCmp(pToken, "EOF") != 0)
  838. {
  839. if (!AsciiToHex(pToken, &currentUnicode))
  840. {
  841. return(FALSE);
  842. }
  843. PARSE_TOKEN(pFile, pToken);
  844. if (StrCmp(pToken, "EOF") != 0)
  845. {
  846. if (!AsciiToHex(pToken, &currentCharCode))
  847. {
  848. return(FALSE);
  849. }
  850. }
  851. else
  852. return(FALSE);
  853. (*pcChars)++;
  854. }
  855. else
  856. return(TRUE);
  857. if ((currentUnicode > (lastUnicode + 1)) ||
  858. (currentCharCode != (lastCharCode + 1)))
  859. {
  860. (*pcRuns)++;
  861. }
  862. lastUnicode = currentUnicode;
  863. lastCharCode = currentCharCode;
  864. }
  865. }
  866. BOOLEAN
  867. BuildUV2CCMap(
  868. PBYTE pFile,
  869. PCMAP pCMap
  870. )
  871. /*++
  872. Routine Description:
  873. Given a memory mapped file ptr to a Unicode to CharCode mapping,
  874. create a CMAP struture which contains char run information.
  875. Arguments:
  876. pFile - Pointer to a memory mapped file.
  877. pCMap - Pointer to pre allocated memory large enough to contain the CMAP.
  878. Return Value:
  879. TRUE => success.
  880. FALSE => error.
  881. --*/
  882. {
  883. PBYTE pToken;
  884. USHORT startUnicode, startCharCode;
  885. USHORT lastUnicode, lastCharCode;
  886. USHORT currentUnicode, currentCharCode;
  887. ULONG cRuns;
  888. BOOL done = FALSE;
  889. startUnicode = startCharCode = 0;
  890. lastUnicode = lastCharCode = 0;
  891. currentUnicode = currentCharCode = 0;
  892. cRuns = 0;
  893. while (!done)
  894. {
  895. PARSE_TOKEN(pFile, pToken);
  896. if (StrCmp(pToken, "EOF") != 0)
  897. {
  898. if (!AsciiToHex(pToken, &currentUnicode))
  899. {
  900. return(FALSE);
  901. }
  902. PARSE_TOKEN(pFile, pToken);
  903. if (StrCmp(pToken, "EOF") != 0)
  904. {
  905. if (!AsciiToHex(pToken, &currentCharCode))
  906. {
  907. return(FALSE);
  908. }
  909. }
  910. else
  911. return(FALSE);
  912. }
  913. else
  914. done = TRUE;
  915. if ((currentUnicode > (lastUnicode + 1)) ||
  916. (currentCharCode != (lastCharCode + 1)) ||
  917. (done))
  918. {
  919. if (startUnicode > 0)
  920. {
  921. pCMap->CMapRange[cRuns].ChCodeStrt = startUnicode;
  922. pCMap->CMapRange[cRuns].cChars = lastUnicode - startUnicode + 1;
  923. pCMap->CMapRange[cRuns].CIDStrt = startCharCode;
  924. cRuns++;
  925. }
  926. startUnicode = currentUnicode;
  927. startCharCode = currentCharCode;
  928. }
  929. lastUnicode = currentUnicode;
  930. lastCharCode = currentCharCode;
  931. }
  932. pCMap->cRuns = cRuns;
  933. return(TRUE);
  934. }
  935. int __cdecl
  936. CmpCMapRunsCID(
  937. const VOID *p1,
  938. const VOID *p2
  939. )
  940. /*++
  941. Routine Description:
  942. Compares the starting CID of two CMAPRANGE structs.
  943. Arguments:
  944. p1, p2 - CMAPRANGEs to compare.
  945. Return Value:
  946. -1 => p1 < p2
  947. 1 => p1 > p2
  948. 0 => p1 = p2
  949. --*/
  950. {
  951. PCMAPRANGE ptr1 = (PCMAPRANGE) p1, ptr2 = (PCMAPRANGE) p2;
  952. //
  953. // Compare starting CIDs of the ranges.
  954. //
  955. if (ptr1->CIDStrt > ptr2->CIDStrt)
  956. return(1);
  957. else if (ptr1->CIDStrt < ptr2->CIDStrt)
  958. return(-1);
  959. else
  960. return(0);
  961. }
  962. int __cdecl
  963. CmpCMapRunsChCode(
  964. const VOID *p1,
  965. const VOID *p2
  966. )
  967. /*++
  968. Routine Description:
  969. Compares the starting Char Code of two CMAPRANGE structs.
  970. Arguments:
  971. p1, p2 - CMAPRANGEs to compare.
  972. Return Value:
  973. -1 => p1 < p2
  974. 1 => p1 > p2
  975. 0 => p1 = p2
  976. --*/
  977. {
  978. PCMAPRANGE ptr1 = (PCMAPRANGE) p1, ptr2 = (PCMAPRANGE) p2;
  979. //
  980. // Compare starting CIDs of the ranges.
  981. //
  982. if (ptr1->ChCodeStrt < ptr2->ChCodeStrt)
  983. return(-1);
  984. else if (ptr1->ChCodeStrt > ptr2->ChCodeStrt)
  985. return(1);
  986. else
  987. return(0);
  988. }
  989. int __cdecl
  990. FindChCodeRun(
  991. const VOID *p1,
  992. const VOID *p2
  993. )
  994. /*++
  995. Routine Description:
  996. Determines if a Charcode falls within a particular CMap run.
  997. Arguments:
  998. p1 - CID
  999. p2 - PCMAPRANGE to check
  1000. Return Value:
  1001. -1 => p1 < p2
  1002. 1 => p1 > p2
  1003. 0 => p1 = p2
  1004. --*/
  1005. {
  1006. PULONG ptr1 = (PULONG) p1;
  1007. PCMAPRANGE ptr2 = (PCMAPRANGE) p2;
  1008. //
  1009. // Determine if CID is in the current range.
  1010. //
  1011. if (*ptr1 < ptr2->ChCodeStrt)
  1012. return(-1);
  1013. else if (*ptr1 >= (ULONG) ptr2->ChCodeStrt + ptr2->cChars)
  1014. return(1);
  1015. else
  1016. return(0);
  1017. }
  1018. int __cdecl
  1019. FindCIDRun(
  1020. const VOID *p1,
  1021. const VOID *p2
  1022. )
  1023. /*++
  1024. Routine Description:
  1025. Determines if a CID falls within a particular CMap run.
  1026. Arguments:
  1027. p1 - CID
  1028. p2 - PCMAPRANGE to check
  1029. Return Value:
  1030. -1 => p1 < p2
  1031. 1 => p1 > p2
  1032. 0 => p1 = p2
  1033. --*/
  1034. {
  1035. PULONG ptr1 = (PULONG) p1;
  1036. PCMAPRANGE ptr2 = (PCMAPRANGE) p2;
  1037. //
  1038. // Determine if CID is in the current range.
  1039. //
  1040. if (*ptr1 < ptr2->CIDStrt)
  1041. return(-1);
  1042. else if (*ptr1 >= ptr2->CIDStrt + ptr2->cChars)
  1043. return(1);
  1044. else
  1045. return(0);
  1046. }
  1047. CHSETSUPPORT
  1048. IsCJKFont(
  1049. PBYTE pAFM
  1050. )
  1051. /*++
  1052. Routine Description:
  1053. Determine if a font is a CJK (Far Eastern) font.
  1054. Arguments:
  1055. pAFM - ptr to memory mapped AFM file
  1056. Return Value:
  1057. 0 - Font not CJK
  1058. Otherwise, font is CJK, and return value is the Win Codepage value
  1059. --*/
  1060. {
  1061. PBYTE pToken;
  1062. USHORT i;
  1063. //
  1064. // Search for CharacterSet token.
  1065. //
  1066. pToken = pAFMCharacterSetString;
  1067. if (pToken == NULL)
  1068. {
  1069. //
  1070. // We can't determine if this font is CJK, so assume it isn't.
  1071. //
  1072. return 0;
  1073. }
  1074. //
  1075. // Search for CharSet (actually Adobe Char Collection) name in CJK table.
  1076. //
  1077. for (i = 0; i < CjkColTbl.usNumEntries; i++)
  1078. {
  1079. if (!StrCmp(pToken, (PBYTE) (((PKEY) (CjkColTbl.pTbl))[i].pName)))
  1080. {
  1081. return(CSUP(((PKEY) (CjkColTbl.pTbl))[i].usValue));
  1082. }
  1083. }
  1084. //
  1085. // Not a recognized CJK font.
  1086. //
  1087. return 0;
  1088. }
  1089. BOOLEAN
  1090. IsVGlyphSet(
  1091. PGLYPHSETDATA pGlyphSetData
  1092. )
  1093. /*++
  1094. Routine Description:
  1095. Determine if a Glyphset is a CJK V variant. Should ONLY be used with
  1096. CJK Glyphsets, otherwise result could be unpredictable!
  1097. Arguments:
  1098. pGlyphSetData - ptr to GLYPHSETDATA
  1099. Return Value:
  1100. TRUE - this is a V variant
  1101. FALSE - not a V variant
  1102. --*/
  1103. {
  1104. PBYTE pName;
  1105. pName = (PBYTE) MK_PTR(pGlyphSetData, dwGlyphSetNameOffset);
  1106. return((pName[strlen(pName) - 1] == 'V'));
  1107. }
  1108. BOOLEAN
  1109. IsCIDFont(
  1110. PBYTE pAFM
  1111. )
  1112. /*++
  1113. Routine Description:
  1114. Determine if a font is a CID font.
  1115. Arguments:
  1116. pAFM - ptr to memory mapped AFM file
  1117. Return Value:
  1118. 0 - Font not clone.
  1119. Otherwise, font is a CID font, and return value non-zero.
  1120. --*/
  1121. {
  1122. PBYTE pToken;
  1123. if (pToken = FindAFMToken(pAFM, PS_CIDFONT_TOK))
  1124. {
  1125. if (!StrCmp(pToken, "true"))
  1126. return TRUE;
  1127. }
  1128. return FALSE;
  1129. }