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.

1854 lines
50 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. newfont.c
  5. Abstract:
  6. Implementation of the functions to use new font format.
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 02/21/97 -eigos-
  11. Support Double byte font
  12. 01/24/97 -eigos-
  13. Filled in functionality
  14. 01/14/97 -ganeshp-
  15. Created
  16. --*/
  17. #include "font.h"
  18. //
  19. //
  20. //
  21. const BYTE aubAnsi[256] =
  22. {
  23. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  24. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  25. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  26. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  27. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  28. 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  29. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  30. 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  31. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  32. 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  33. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  34. 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  35. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  36. 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  37. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  38. 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  39. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  40. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  41. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  42. 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  43. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  44. 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  45. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  46. 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  47. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  48. 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  49. 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  50. 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  51. 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  52. 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  53. 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  54. 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  55. };
  56. //
  57. // Macro definition
  58. //
  59. #define DW_MASK (DWBITS - 1)
  60. //
  61. // Internal function prototype
  62. //
  63. BOOL
  64. BExtractGTT(
  65. PUNI_GLYPHSETDATA pGTT,
  66. WCHAR wchFirst,
  67. WCHAR wchLast,
  68. FD_GLYPHSET *pFD_GLYPHSET,
  69. PDWORD pdwFD_GLYPHSETSize);
  70. BOOL
  71. BExtractGTTwithPredefGTT(
  72. IN PUNI_GLYPHSETDATA pPreDefGTT,
  73. IN PUNI_GLYPHSETDATA pMiniDefGTT,
  74. IN WCHAR wchFirst,
  75. IN WCHAR wchLast,
  76. OUT FD_GLYPHSET **ppFD_GLYPHSET,
  77. OUT PMAPTABLE *pMapTable,
  78. IN PDWORD pdwFD_GLYPHSETSize);
  79. SHORT
  80. SGetWidth(
  81. PWIDTHTABLE pWidthTable,
  82. HGLYPH hg);
  83. BYTE ubGetAnsi(
  84. WCHAR,
  85. INT,
  86. PWCHAR,
  87. PBYTE);
  88. DWORD
  89. DwCheckTrans(
  90. PGLYPHRUN pMiniGlyphRun,
  91. PMAPTABLE pMiniMapTable,
  92. DWORD dwMiniGlyphRunCount,
  93. WORD wUnicode);
  94. WCHAR
  95. WchGetNextUnicode(
  96. PWCHAR pwchUnicode,
  97. PDWORD pdwUnicodeBits,
  98. INT iNumOfHandle);
  99. int __cdecl Comp(const void *elem1, const void *elem2);
  100. //
  101. //
  102. // Functions
  103. //
  104. //
  105. VOID*
  106. PVGetUCFD_GLYPHSET(
  107. PDEV *pPDev,
  108. FONTMAP *pFM
  109. )
  110. /*++
  111. Routine Description:
  112. Arguments:
  113. pPDev Pointer to PDEV
  114. Return Value:
  115. TRUE for success and FALSE for failure
  116. Note:
  117. 01/14/97 -ganeshp-
  118. Created it.
  119. --*/
  120. {
  121. PFONTMAP_DEV pFMDev;
  122. PVOID pvFD_GLYPHSET = NULL;
  123. DWORD dwFD_GLYPHSETSize;
  124. //
  125. // Paremeter validation
  126. //
  127. ASSERT(pFM != NULL);
  128. pFMDev = pFM->pSubFM;
  129. pvFD_GLYPHSET = NULL;
  130. if (pFMDev->pvNTGlyph)
  131. {
  132. #if ENABLE_GTT_COMBINE
  133. RES_ELEM ResElem;
  134. if (((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph)->lPredefinedID !=
  135. CC_NOPRECNV)
  136. {
  137. if (BGetWinRes( &(pPDev->WinResData),
  138. ((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph)->lPredefinedID,
  139. RC_GTT,
  140. &ResElem))
  141. {
  142. pFMDev->pvPredefGTT = ResElem.pvResData;
  143. BExtractGTTwithPredefGTT(pFMDev->pvPredefGTT,
  144. pFMDev->pvNTGlyph,
  145. pFM->wFirstChar,
  146. pFM->wLastChar,
  147. pvFD_GLYPHSET,
  148. (PMAPTABLE*)&pFMDev->pvMapTable,
  149. &dwFD_GLYPHSETSize);
  150. }
  151. else
  152. {
  153. pFMDev->pvPredefGTT = NULL;
  154. ERR(("UniFont!PVGetUCFD_GLYPHSET: pvNTGTT is no loaded.\n"));
  155. }
  156. }
  157. #endif
  158. //
  159. // First, try to get Far East Stock FD_GLYPHSET.
  160. //
  161. #if ENABLE_STOCKGLYPHSET
  162. if (!BGetStockGlyphset( pPDev, &pvFD_GLYPHSET, (SHORT)pFMDev->sCTTid))
  163. {
  164. if (!BExtractGTT((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph,
  165. pFM->wFirstChar,
  166. pFM->wLastChar,
  167. (FD_GLYPHSET*)NULL,
  168. (PDWORD)&dwFD_GLYPHSETSize) ||
  169. !(pvFD_GLYPHSET = MemAlloc(dwFD_GLYPHSETSize)) ||
  170. !BExtractGTT((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph,
  171. pFM->wFirstChar,
  172. pFM->wLastChar,
  173. (FD_GLYPHSET*)pvFD_GLYPHSET,
  174. (PDWORD)&dwFD_GLYPHSETSize))
  175. {
  176. if (pvFD_GLYPHSET)
  177. {
  178. MemFree(pvFD_GLYPHSET);
  179. pvFD_GLYPHSET = NULL;
  180. ERR(("UniFont!PVGetUCFD_GLYPHSET failed\n"));
  181. }
  182. }
  183. }
  184. #else
  185. if (!BExtractGTT((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph,
  186. pFM->wFirstChar,
  187. pFM->wLastChar,
  188. (FD_GLYPHSET*)NULL,
  189. (PDWORD)&dwFD_GLYPHSETSize) ||
  190. !(pvFD_GLYPHSET = MemAlloc(dwFD_GLYPHSETSize)) ||
  191. !BExtractGTT((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph,
  192. pFM->wFirstChar,
  193. pFM->wLastChar,
  194. (FD_GLYPHSET*)pvFD_GLYPHSET,
  195. (PDWORD)&dwFD_GLYPHSETSize))
  196. {
  197. if (pvFD_GLYPHSET)
  198. {
  199. MemFree(pvFD_GLYPHSET);
  200. pvFD_GLYPHSET = NULL;
  201. ERR(("UniFont!PVGetUCFD_GLYPHSET failed\n"));
  202. }
  203. }
  204. #endif
  205. }
  206. else
  207. {
  208. ERR(("UniFont!PVGetUCFD_GLYPHSET: pvNTGTT is no loaded.\n"));
  209. }
  210. pFMDev->pUCTree = pvFD_GLYPHSET;
  211. return pvFD_GLYPHSET;
  212. }
  213. VOID *
  214. PVUCKernPair(
  215. PDEV *pPDev,
  216. FONTMAP *pFM
  217. )
  218. /*++
  219. Routine Description:
  220. Arguments:
  221. pPDev Pointer to PDEV
  222. Return Value:
  223. TRUE for success and FALSE for failure
  224. Note:
  225. 01/14/97 -ganeshp-
  226. Created it.
  227. --*/
  228. {
  229. PFONTMAP_DEV pFMDev;
  230. PKERNDATA pKerningData;
  231. PUNIFM_HDR pUFM;
  232. PVOID pvKernPair = NULL;
  233. //
  234. // Paremeter validation
  235. //
  236. ASSERT(pFM != NULL);
  237. pFMDev = pFM->pSubFM;
  238. pUFM = pFMDev->pvFontRes;
  239. if (pFM->flFlags & FM_KERNRES)
  240. {
  241. pvKernPair = pFMDev->pUCKernTree;
  242. }
  243. else
  244. if (pUFM && pUFM->loKernPair)
  245. {
  246. pKerningData = GET_KERNDATA(pUFM);
  247. pFMDev->pUCKernTree = pKerningData->KernPair;
  248. pFM->flFlags |= FM_KERNRES;
  249. }
  250. return pvKernPair;
  251. }
  252. BOOL
  253. BGetNewFontInfo(
  254. FONTMAP *pFM,
  255. BYTE *pRes)
  256. /*++
  257. Routine Description:
  258. Arguments:
  259. pfm Pointer to FONTMAP
  260. pRes Pointer to UFM resource
  261. Return Value:
  262. TRUE for success and FALSE for failure
  263. Note:
  264. 01/14/97 -ganeshp-
  265. Created it.
  266. --*/
  267. {
  268. PUNIFM_HDR pUFM;
  269. PUNIDRVINFO pUnidrvInfo;
  270. PIFIMETRICS pIFI;
  271. PKERNDATA pKerningData;
  272. PFONTMAP_DEV pFMDev;
  273. //
  274. // Paremeter validation
  275. //
  276. ASSERT(pFM != NULL || pRes != NULL);
  277. //
  278. // Get UFM data
  279. //
  280. pFMDev = pFM->pSubFM;
  281. pFMDev->pvFontRes = pRes;
  282. pUFM = (PUNIFM_HDR)pRes;
  283. if (pUFM == NULL ||
  284. pUFM->loIFIMetrics == 0)
  285. {
  286. ERR(("UniFont!BGetNewFontInfo failed: Invalid FONTMAP.pUFMFontRes\n"));
  287. SetLastError( ERROR_INVALID_PARAMETER );
  288. return FALSE;
  289. }
  290. //
  291. // Get data pointer of UFM
  292. //
  293. pUnidrvInfo = GET_UNIDRVINFO(pUFM);
  294. //
  295. // Fill out FONTMAP members
  296. //
  297. if (0 != pUFM->loIFIMetrics % sizeof(PVOID))
  298. {
  299. DWORD dwSize;
  300. pIFI = GET_IFIMETRICS(pUFM);
  301. if (NULL == pIFI)
  302. {
  303. return FALSE;
  304. }
  305. dwSize = ((IFIMETRICS UNALIGNED *)(pIFI))->cjThis;
  306. if (pFM->pIFIMet = MemAlloc(dwSize))
  307. {
  308. CopyMemory(pFM->pIFIMet, pIFI, dwSize);
  309. pIFI = pFM->pIFIMet;
  310. pFM->flFlags &= ~FM_IFIRES;
  311. }
  312. else
  313. return FALSE;
  314. }
  315. else
  316. {
  317. pIFI = GET_IFIMETRICS(pUFM);
  318. pFM->pIFIMet = pIFI;
  319. pFM->flFlags = FM_IFIRES;
  320. }
  321. if (pUnidrvInfo->SelectFont.dwCount && pUnidrvInfo->SelectFont.loOffset)
  322. {
  323. pFMDev->cmdFontSel.FInv.dwCount =
  324. pUnidrvInfo->SelectFont.dwCount;
  325. pFMDev->cmdFontSel.FInv.pubCommand =
  326. GET_SELECT_CMD(pUnidrvInfo);
  327. pFM->flFlags |= FM_FINVOC | FM_FONTCMD;
  328. }
  329. if (pUnidrvInfo->UnSelectFont.dwCount && pUnidrvInfo->UnSelectFont.loOffset)
  330. {
  331. pFMDev->cmdFontDesel.FInv.dwCount =
  332. pUnidrvInfo->UnSelectFont.dwCount;
  333. pFMDev->cmdFontDesel.FInv.pubCommand =
  334. GET_UNSELECT_CMD(pUnidrvInfo);
  335. pFM->flFlags |= FM_FINVOC | FM_FONTCMD;
  336. }
  337. if (pUFM->loExtTextMetric)
  338. {
  339. pFMDev->pETM = GET_EXTTEXTMETRIC(pUFM);
  340. }
  341. if (pUFM->loWidthTable)
  342. {
  343. pFMDev->W.pWidthTable = GET_WIDTHTABLE(pUFM);
  344. pFM->flFlags |= FM_WIDTHRES;
  345. }
  346. if (pUFM->loKernPair)
  347. {
  348. pKerningData = GET_KERNDATA(pUFM);
  349. pFMDev->pUCKernTree = pKerningData->KernPair;
  350. pFM->flFlags |= FM_KERNRES;
  351. }
  352. pFMDev->wDevFontType = pUnidrvInfo->wType;
  353. pFMDev->ulCodepage = pUFM->ulDefaultCodepage;
  354. pFM->wFirstChar = pIFI->wcFirstChar;
  355. pFM->wLastChar = pIFI->wcLastChar;
  356. pFM->wXRes = pUnidrvInfo->wXRes;
  357. pFM->wYRes = pUnidrvInfo->wYRes;
  358. pFMDev->sYAdjust = pUnidrvInfo->sYAdjust;
  359. pFMDev->sYMoved = pUnidrvInfo->sYMoved;
  360. pFMDev->sCTTid = (SHORT)pUFM->lGlyphSetDataRCID;
  361. pFMDev->fCaps = pUnidrvInfo->fCaps;
  362. return TRUE;
  363. }
  364. INT
  365. IGetUFMGlyphWidth(
  366. PDEV *pPDev,
  367. FONTMAP *pFM,
  368. HGLYPH hg
  369. )
  370. /*++
  371. Routine Description:
  372. Arguments:
  373. pFM Pointer to FONTMAP
  374. Return Value:
  375. Width
  376. Note:
  377. 01/14/97 -ganeshp-
  378. Created it.
  379. --*/
  380. {
  381. return IGetUFMGlyphWidthJr(&(pPDev->ptGrxRes), pFM, hg);
  382. }
  383. INT
  384. IGetUFMGlyphWidthJr(
  385. POINT *pptGrxRes,
  386. FONTMAP *pFM,
  387. HGLYPH hg
  388. )
  389. /*++
  390. Routine Description:
  391. Arguments:
  392. pFM Pointer to FONTMAP
  393. Return Value:
  394. Width
  395. Note:
  396. 01/14/97 -ganeshp-
  397. Created it.
  398. --*/
  399. {
  400. TRANSDATA *pTrans;
  401. MAPTABLE *pMapTable;
  402. FONTMAP_DEV *pFMDev;
  403. INT iGlyphWidth;
  404. //
  405. // UNIDRV returns 1 for the first glyph handle in FD_GLYPHSET.
  406. // However, GDI could pass zero in hg.
  407. // We need to handle this GDI error properly.
  408. //
  409. if (NULL == pFM || NULL == pptGrxRes || 0 == hg)
  410. {
  411. return 0;
  412. }
  413. pFMDev = pFM->pSubFM;
  414. if ((pFM->flFlags & FM_WIDTHRES) &&
  415. (iGlyphWidth = SGetWidth(pFMDev->W.pWidthTable, hg)))
  416. {
  417. iGlyphWidth = iGlyphWidth * pptGrxRes->x / pFM->wXRes;
  418. }
  419. else
  420. {
  421. pMapTable = GET_MAPTABLE(pFMDev->pvNTGlyph);
  422. pTrans = pMapTable->Trans;
  423. if (IS_DBCSCHARSET(((IFIMETRICS*)pFM->pIFIMet)->jWinCharSet))
  424. {
  425. if (pTrans[hg - 1].ubType & MTYPE_DOUBLE)
  426. {
  427. iGlyphWidth = (INT)((PIFIMETRICS)pFM->pIFIMet)->fwdMaxCharInc;
  428. //VERBOSE(("(2)MTYPE_DOUBLE:Char=0x%x%x, ",
  429. // pTrans[hg-1].uCode.ubPairs[0],
  430. // pTrans[hg-1].uCode.ubPairs[1]));
  431. }
  432. else
  433. {
  434. iGlyphWidth = (INT)((PIFIMETRICS)pFM->pIFIMet)->fwdAveCharWidth;
  435. //VERBOSE(("(2)MTYPE_SINGLE:Char=%d, ",
  436. // pTrans[hg-1].uCode.ubCode));
  437. }
  438. }
  439. else
  440. {
  441. iGlyphWidth = (INT)((PIFIMETRICS)pFM->pIFIMet)->fwdMaxCharInc;
  442. }
  443. }
  444. //VERBOSE(("Width=%d\n",iGlyphWidth));
  445. return iGlyphWidth;
  446. }
  447. BOOL
  448. BGTTOutputGlyph(
  449. TO_DATA *pTod)
  450. /*++
  451. Routine Description:
  452. Same as BRLEOutputGlyph in textout.c. Should use GTT data instead of
  453. RLE.
  454. Arguments:
  455. pTod - a pointer to TEXTOUT DATA (TO_DATA) structure
  456. Return Value:
  457. TRUE for success and FALSE for failure
  458. Note:
  459. 02/14/97 -eigos-
  460. Created it.
  461. --*/
  462. {
  463. FONTPDEV *pFontPDev;
  464. IFIMETRICS *pIFIMetrics;
  465. PUNI_GLYPHSETDATA pGlyphSetData;
  466. PUNI_CODEPAGEINFO pCodePageInfo;
  467. PMAPTABLE pMapTable;
  468. COMMAND *pCmd;
  469. PTRANSDATA pTrans;
  470. PFONTMAP_DEV pFMDev;
  471. PDEV *pPDev;
  472. HGLYPH hg;
  473. FONTMAP *pFM;
  474. PGLYPHPOS pgp;
  475. POINTL ptlRem;
  476. PBYTE pString;
  477. DWORD dwSize, cGlyphs;
  478. INT iX, iY, iXInc, iYInc;
  479. BOOL bRet;
  480. BOOL bSetCursorForEachGlyph;
  481. pPDev = pTod->pPDev;
  482. pFontPDev = pPDev->pFontPDev;
  483. pFM = pTod->pfm;
  484. pIFIMetrics = (IFIMETRICS*)pFM->pIFIMet;
  485. pFMDev = pFM->pSubFM;
  486. pGlyphSetData = (PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph;
  487. cGlyphs = pTod->cGlyphsToPrint;
  488. pgp = pTod->pgp;
  489. bSetCursorForEachGlyph = SET_CURSOR_FOR_EACH_GLYPH(pTod->flAccel);
  490. if (!bSetCursorForEachGlyph ||
  491. pFontPDev->flFlags & FDV_DISABLE_POS_OPTIMIZE)
  492. {
  493. //
  494. // If bSetCursorForEachGlyph is not set, send the first character's
  495. // position.
  496. //
  497. // FDV_DISABLE_POS_OPTIMIZE
  498. // If there is rounding error, when scaling width,
  499. // disable x position optimization
  500. //
  501. VSetCursor( pPDev, pgp->ptl.x, pgp->ptl.y, MOVE_ABSOLUTE, &ptlRem);
  502. }
  503. pTod->flFlags |= TODFL_FIRST_GLYPH_POS_SET;
  504. //
  505. // Set the cursor to the desired X position for this glyph. NOTE
  506. // that we should only use RELATIVE move commands in here, since
  507. // the LaserJet family rotates the COORDINATE AXES when text is
  508. // being rotated by multiples of 90 degrees. Using relative moves
  509. // means we can avoid trying to figure out where the printer thinks
  510. // the print positiion is located. It's almost guaranteed to be
  511. // different to what we think it is!
  512. //
  513. // DCR - should reorganise the move command code to do a better
  514. // job here. Problem is that if we are rotating the bitmap, then MV_FINE
  515. // is NOT a good idea, since it almost undoubtedly move the cursor in
  516. // the WRONG dimension! When we are rotating the bitmap, it is most
  517. // probable that the MV_FINE will move in the Y direction!!!
  518. //
  519. bRet = TRUE;
  520. iX = iY = 0;
  521. if (pGlyphSetData != NULL)
  522. {
  523. while (cGlyphs --)
  524. {
  525. //
  526. // Do nothing. GDI could pass ZERO HGLYPH.
  527. // GTT glyph handle starts from 1. GDI is not supposed to pass 0 in
  528. // HGLYPH.
  529. //
  530. if (0 == pgp->hg)
  531. continue;
  532. hg = pgp->hg;
  533. iX = pgp->ptl.x;
  534. iY = pgp->ptl.y;
  535. //
  536. // Move to the next character's position
  537. //
  538. if (bSetCursorForEachGlyph)
  539. VSetCursor( pPDev, iX, iY, MOVE_ABSOLUTE, &ptlRem);
  540. //
  541. // Minidriver defined glyph conversion
  542. //
  543. pMapTable = GET_MAPTABLE((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph);
  544. pTrans = pMapTable->Trans;
  545. //
  546. // Send symbol set selection command
  547. //
  548. if ( pFMDev->ulCodepageID != pTrans[hg - 1].ubCodePageID )
  549. {
  550. if (pFMDev->ulCodepageID != -1)
  551. {
  552. pCodePageInfo = GET_CODEPAGEINFO((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph);
  553. pCodePageInfo += pFMDev->ulCodepageID;
  554. pString = (PBYTE)pCodePageInfo +
  555. pCodePageInfo->UnSelectSymbolSet.loOffset;
  556. dwSize = pCodePageInfo->UnSelectSymbolSet.dwCount;
  557. if (dwSize)
  558. {
  559. WriteSpoolBuf(pPDev, pString, dwSize);
  560. }
  561. }
  562. pFMDev->ulCodepageID = pTrans[hg - 1].ubCodePageID;
  563. pCodePageInfo = GET_CODEPAGEINFO((PUNI_GLYPHSETDATA)pFMDev->pvNTGlyph);
  564. pCodePageInfo += pFMDev->ulCodepageID;
  565. pString = (PBYTE)pCodePageInfo +
  566. pCodePageInfo->SelectSymbolSet.loOffset;
  567. dwSize = pCodePageInfo->SelectSymbolSet.dwCount;
  568. if (dwSize)
  569. {
  570. WriteSpoolBuf(pPDev, pString, dwSize);
  571. }
  572. }
  573. //
  574. // Single/Double byte mode switch
  575. //
  576. if ((pTrans[hg - 1].ubType & MTYPE_SINGLE) &&
  577. !(pFontPDev->flFlags & FDV_SINGLE_BYTE) )
  578. {
  579. if(pCmd = COMMANDPTR(pPDev->pDriverInfo, CMD_SELECTSINGLEBYTEMODE))
  580. {
  581. pFontPDev->flFlags &= ~FDV_DOUBLE_BYTE;
  582. pFontPDev->flFlags |= FDV_SINGLE_BYTE;
  583. WriteChannel( pPDev, pCmd );
  584. }
  585. else
  586. pFontPDev->flFlags |= FDV_SINGLE_BYTE;
  587. }
  588. else
  589. if ((pTrans[hg - 1].ubType & MTYPE_DOUBLE) &&
  590. !(pFontPDev->flFlags & FDV_DOUBLE_BYTE) )
  591. {
  592. if (pCmd = COMMANDPTR(pPDev->pDriverInfo, CMD_SELECTDOUBLEBYTEMODE))
  593. {
  594. pFontPDev->flFlags |= FDV_DOUBLE_BYTE;
  595. pFontPDev->flFlags &= ~FDV_SINGLE_BYTE;
  596. WriteChannel( pPDev, pCmd );
  597. }
  598. else
  599. pFontPDev->flFlags |= FDV_DOUBLE_BYTE;
  600. }
  601. //
  602. // Send string
  603. //
  604. switch(MTYPE_FORMAT_MASK & pTrans[hg - 1].ubType)
  605. {
  606. case MTYPE_DIRECT:
  607. bRet = WriteSpoolBuf(pPDev, &(pTrans[hg - 1].uCode.ubCode), 1) == 1;
  608. break;
  609. case MTYPE_PAIRED:
  610. //
  611. // First, try to use cursor push/pop escapes to
  612. // overlay the 2 characters. If they are not
  613. // available, try the backspace. If it doesn't exist
  614. // either, ignore the second character.
  615. //
  616. pCmd = COMMANDPTR(pPDev->pDriverInfo, CMD_PUSHCURSOR);
  617. pString = pTrans[hg - 1].uCode.ubPairs;
  618. if (pTrans[hg - 1].ubType & (MTYPE_SINGLE|MTYPE_DOUBLE))
  619. {
  620. bRet = WriteSpoolBuf( pPDev, pString, 2 ) == 2;
  621. }
  622. else
  623. {
  624. if ( *(pString + 1) && (pCmd != NULL) )
  625. {
  626. //
  627. // Pushed the position; output ch1, pop position, ch2
  628. //
  629. bRet = WriteSpoolBuf( pPDev, pString, 1 ) == 1;
  630. WriteChannel( pPDev, pCmd );
  631. bRet = WriteSpoolBuf( pPDev, pString + 1, 1 ) == 1;
  632. }
  633. else
  634. {
  635. pCmd = COMMANDPTR(pPDev->pDriverInfo, CMD_BACKSPACE);
  636. bRet = WriteSpoolBuf( pPDev, pString, 1 ) == 1;
  637. if( (*(pString + 1)) && (pFontPDev->flFlags & FDV_BKSP_OK) )
  638. {
  639. WriteChannel( pPDev, pCmd );
  640. bRet = WriteSpoolBuf( pPDev, pString + 1, 1 ) == 1;
  641. }
  642. }
  643. }
  644. break;
  645. case MTYPE_COMPOSE:
  646. pString = (PBYTE)pMapTable + pTrans[hg - 1].uCode.sCode;
  647. bRet = (WriteSpoolBuf(pPDev, pString + 2, *(WORD UNALIGNED *)pString) ==
  648. *(WORD UNALIGNED *)pString);
  649. break;
  650. }
  651. pgp++;
  652. //
  653. // After drawing the character, in the printer, the cursor position
  654. // moves. Update the UNIDRV internal value to reduce the amount of
  655. // command to send.
  656. //
  657. if (bSetCursorForEachGlyph)
  658. {
  659. if( pFM->flFlags & FM_WIDTHRES)
  660. {
  661. if ((iXInc = SGetWidth(pFMDev->W.pWidthTable, hg)))
  662. iXInc = iXInc * pPDev->ptGrxRes.x / pFM->wXRes;
  663. else
  664. iXInc = pIFIMetrics->fwdAveCharWidth;
  665. }
  666. else
  667. {
  668. if (pTrans[hg - 1].ubType & MTYPE_DOUBLE)
  669. iXInc = pIFIMetrics->fwdMaxCharInc;
  670. else
  671. iXInc = pIFIMetrics->fwdAveCharWidth;
  672. }
  673. if (pFM->flFlags & FM_SCALABLE)
  674. {
  675. iXInc = LMulFloatLong(&pFontPDev->ctl.eXScale,iXInc);
  676. }
  677. if (pTod->flAccel & SO_VERTICAL)
  678. {
  679. iYInc = iXInc;
  680. iXInc = 0;
  681. }
  682. else
  683. {
  684. iYInc = 0;
  685. }
  686. VSetCursor( pPDev,
  687. iXInc,
  688. iYInc,
  689. MOVE_RELATIVE|MOVE_UPDATE,
  690. &ptlRem);
  691. }
  692. }
  693. }
  694. else
  695. {
  696. bRet = FALSE;
  697. }
  698. if (bRet && pFM)
  699. {
  700. if (!bSetCursorForEachGlyph)
  701. {
  702. //
  703. // Output may have successed, so update the position.
  704. //
  705. if (pFM->flFlags & FM_WIDTHRES)
  706. {
  707. if (!(iXInc = SGetWidth(pFMDev->W.pWidthTable, hg)))
  708. iXInc = pIFIMetrics->fwdAveCharWidth;
  709. }
  710. else
  711. {
  712. if (pTrans[hg - 1].ubType & MTYPE_DOUBLE)
  713. {
  714. iXInc = pIFIMetrics->fwdMaxCharInc;
  715. }
  716. else
  717. {
  718. iXInc = pIFIMetrics->fwdAveCharWidth;
  719. }
  720. }
  721. if (pFM->flFlags & FM_SCALABLE)
  722. {
  723. //
  724. // Need to transform the value to current size
  725. //
  726. iXInc = LMulFloatLong(&pFontPDev->ctl.eXScale,iXInc);
  727. }
  728. if (pTod->flAccel & SO_VERTICAL)
  729. {
  730. iYInc = iXInc;
  731. iXInc = 0;
  732. }
  733. else
  734. {
  735. iYInc = 0;
  736. }
  737. VSetCursor( pPDev,
  738. (iX + iXInc) - pTod->pgp->ptl.x,
  739. (iY + iYInc) - pTod->pgp->ptl.y,
  740. MOVE_RELATIVE | MOVE_UPDATE,
  741. &ptlRem);
  742. }
  743. }
  744. else
  745. {
  746. bRet = FALSE;
  747. }
  748. return bRet;
  749. }
  750. BOOL
  751. BGTTSelectFont(
  752. PDEV *pPDev,
  753. PFONTMAP pFM,
  754. POINTL *pptl)
  755. {
  756. PFONTMAP_DEV pfmdev;
  757. INT iCmdLength;
  758. PBYTE pbCmd;
  759. pfmdev = pFM->pSubFM;
  760. if ((iCmdLength = (INT)pfmdev->cmdFontSel.FInv.dwCount) &&
  761. (pbCmd = pfmdev->cmdFontSel.FInv.pubCommand))
  762. {
  763. pfmdev->pfnDevSelFont( pPDev, pbCmd, iCmdLength, pptl);
  764. }
  765. //
  766. // Reset uLCodepageID to send codepage selection command.
  767. //
  768. pfmdev->ulCodepageID = (ULONG)-1;
  769. ((PFONTPDEV)pPDev->pFontPDev)->flFlags &= ~FDV_DOUBLE_BYTE | FDV_SINGLE_BYTE;
  770. return TRUE;
  771. }
  772. BOOL
  773. BGTTDeselectFont(
  774. PDEV *pPDev,
  775. PFONTMAP pFM)
  776. {
  777. PFONTMAP_DEV pfmdev;
  778. INT iCmdLength;
  779. PBYTE pbCmd;
  780. pfmdev = pFM->pSubFM;
  781. if ((iCmdLength = (INT)pfmdev->cmdFontDesel.FInv.dwCount) &&
  782. (pbCmd = pfmdev->cmdFontDesel.FInv.pubCommand) &&
  783. iCmdLength != WriteSpoolBuf( pPDev, pbCmd, iCmdLength) )
  784. {
  785. return FALSE;
  786. }
  787. return TRUE;
  788. }
  789. //
  790. //
  791. // Internal functions
  792. //
  793. //
  794. BOOL
  795. BExtractGTT(
  796. PUNI_GLYPHSETDATA pGTT,
  797. WCHAR wchFirst,
  798. WCHAR wchLast,
  799. FD_GLYPHSET *pFD_GLYPHSET,
  800. PDWORD pdwFD_GLYPHSETSize)
  801. /*++
  802. Routine Description:
  803. Create FD_GLYPHSET from GLYPHRUN in GTT.
  804. Arguments:
  805. pGTT - GTT file resource
  806. pFD_GLYPHSET - a buffer to be filled out
  807. pdwFD_GLYPHSETSize - a pointer to the size of FD_GLYPHSET
  808. Return Value:
  809. TRUE for success and FALSE for failure
  810. Note:
  811. --*/
  812. {
  813. PGLYPHRUN pGlyphRun;
  814. HGLYPH GlyphHandle, *pGlyphHandle;
  815. DWORD dwI, dwGlyphNum;
  816. WORD wJ;
  817. //
  818. // parameter validation
  819. //
  820. ASSERT(pGTT != NULL);
  821. if (pFD_GLYPHSET == NULL)
  822. {
  823. //
  824. // pFD_GLYPHSET == NULL case
  825. // return the necessary amount of memory
  826. //
  827. pGlyphRun = GET_GLYPHRUN(pGTT);
  828. dwGlyphNum = 0;
  829. for (dwI = 0; dwI < pGTT->dwRunCount; dwI ++, pGlyphRun ++)
  830. {
  831. dwGlyphNum += pGlyphRun->wGlyphCount;
  832. }
  833. *pdwFD_GLYPHSETSize = sizeof(FD_GLYPHSET) +
  834. (pGTT->dwRunCount - 1) * sizeof(WCRUN) +
  835. dwGlyphNum * sizeof(HGLYPH);
  836. }
  837. else
  838. {
  839. //
  840. // pFD_GLYPHSET != NULL case
  841. // Fill out pFD_GLYPHSET
  842. //
  843. pFD_GLYPHSET->cjThis = *pdwFD_GLYPHSETSize;
  844. pFD_GLYPHSET->flAccel = 0;
  845. pFD_GLYPHSET->cGlyphsSupported = 0;
  846. pFD_GLYPHSET->cRuns = pGTT->dwRunCount;
  847. pGlyphHandle = (HGLYPH*)( (PBYTE)pFD_GLYPHSET +
  848. sizeof(FD_GLYPHSET) +
  849. sizeof(WCRUN) * (pGTT->dwRunCount-1) );
  850. pGlyphRun = GET_GLYPHRUN(pGTT);
  851. dwGlyphNum = 0;
  852. //
  853. // IMPORTANT!!!: Glyph handle in FD_GLYPHSET starts from 1 for GTT.
  854. //
  855. GlyphHandle = 1;
  856. for (dwI = 0; dwI < pGTT->dwRunCount; dwI ++, pGlyphRun ++)
  857. {
  858. dwGlyphNum += pGlyphRun->wGlyphCount;
  859. pFD_GLYPHSET->awcrun[dwI].cGlyphs = pGlyphRun->wGlyphCount;
  860. pFD_GLYPHSET->awcrun[dwI].wcLow = pGlyphRun->wcLow;
  861. pFD_GLYPHSET->awcrun[dwI].phg = pGlyphHandle;
  862. for (wJ = 0; wJ < pGlyphRun->wGlyphCount; wJ ++,
  863. pGlyphHandle ++,
  864. GlyphHandle ++)
  865. {
  866. *pGlyphHandle = GlyphHandle;
  867. }
  868. }
  869. pFD_GLYPHSET->cGlyphsSupported = dwGlyphNum;
  870. }
  871. return TRUE;
  872. }
  873. SHORT
  874. SGetWidth(
  875. PWIDTHTABLE pWidthTable,
  876. HGLYPH hg)
  877. {
  878. // Because of a problem in at least one very common font resource DLL (HPCFONT.DLL)
  879. // already out and about, it's safer and easier to access this table in an unaligned
  880. // memory location than to try move it to align it.
  881. PWIDTHRUN pWidthRun = pWidthTable->WidthRun;
  882. SHORT UNALIGNED *psWidth;
  883. DWORD dwRunCount = 0;
  884. while ( ( hg < (ULONG)(*((SHORT UNALIGNED *)&(pWidthRun->wStartGlyph)) ) ||
  885. (ULONG)( *((SHORT UNALIGNED *)&(pWidthRun->wStartGlyph)) )
  886. + ( *((SHORT UNALIGNED *)&(pWidthRun->wGlyphCount)) ) <= hg ) &&
  887. dwRunCount < ( *((DWORD UNALIGNED *)&(pWidthTable->dwRunNum)) ) )
  888. {
  889. pWidthRun ++;
  890. dwRunCount ++;
  891. }
  892. if (dwRunCount == ( *((SHORT UNALIGNED *)&(pWidthTable->dwRunNum)) ))
  893. {
  894. return 0;
  895. }
  896. else
  897. {
  898. DWORD dwOffset = *( (DWORD UNALIGNED *) (&(pWidthRun->loCharWidthOffset)) );
  899. psWidth = ((SHORT UNALIGNED *)( (PBYTE)pWidthTable + dwOffset ));
  900. return psWidth[hg - ( *((SHORT UNALIGNED *)&(pWidthRun->wStartGlyph)) )];
  901. }
  902. }
  903. PUNI_GLYPHSETDATA
  904. PNTGTT1To1(
  905. IN DWORD dwCodePage,
  906. IN BOOL bSymbolCharSet,
  907. IN INT iFirstChar,
  908. IN INT iLastChar)
  909. /*++
  910. Routine Description:
  911. Generates a simple mapping format for the GTT stuff. This is
  912. typically used for a printer with a 1:1 mapping to the Windows
  913. character set.
  914. Arguments:
  915. iFirst: The lowest glyph in the range.
  916. iLast: The last glyph in the range (inclusive)
  917. Return Value:
  918. Address of GTT structure allocated from heap; NULL on failure.
  919. Note:
  920. 11-27-96: Created it -ganeshp-
  921. --*/
  922. {
  923. PUNI_CODEPAGEINFO pCodePageInfo;
  924. PGLYPHRUN pGlyphRun, pGlyphRunOrg;
  925. TRANSDATA *pTrans;
  926. PMAPTABLE pMapTable;
  927. USHORT usAnsiCodePage, usOEMCodePage;
  928. INT iNumOfHandle, iNumOfRuns, iTotalGlyphSetDataSize, iNumOfUnsupportChar;
  929. INT iI, iJ, iK, iIndex;
  930. WCHAR awchUnicode[256];
  931. struct {
  932. WORD wID;
  933. WCHAR Unicode;
  934. } UnicodeDst[256];
  935. WCHAR wchChar, wchCurrent, wchTemp;
  936. PBYTE pbBase;
  937. ASSERT(iFirstChar == 0x20 && iLastChar == 0xFF);
  938. iNumOfUnsupportChar = 0;
  939. iNumOfHandle = iLastChar - iFirstChar + 1;
  940. if (iNumOfHandle > 256)
  941. {
  942. ERR(("UniFont!NTGTT1To1 failed:iNumOfHandle > 256.\n"));
  943. return NULL;
  944. }
  945. if (dwCodePage == 0)
  946. {
  947. dwCodePage = 1252;
  948. }
  949. #ifndef WINNT_40 // NT 5.0
  950. if( -1 == (iNumOfHandle = EngMultiByteToWideChar(dwCodePage,
  951. awchUnicode,
  952. (INT)(iNumOfHandle * sizeof(WCHAR)),
  953. (PCH)aubAnsi+iFirstChar,
  954. (INT)iNumOfHandle)))
  955. {
  956. ERR(("UniFont!NTGTT1To1:EngMultiByteToWideChar failed\n"));
  957. return NULL;
  958. }
  959. #else
  960. EngMultiByteToUnicodeN(awchUnicode, iNumOfHandle * sizeof(WCHAR), NULL, (PBYTE)aubAnsi+iFirstChar, iNumOfHandle);
  961. //
  962. // Disable new symbol set character range on NT4 (F020 to F0FF)
  963. //
  964. bSymbolCharSet = FALSE;
  965. #endif // WINNT_40
  966. wchCurrent = 0;
  967. iNumOfRuns = 0;
  968. for (iI = 0; iI < iNumOfHandle; iI ++)
  969. {
  970. UnicodeDst[iI].wID = iI+iFirstChar;
  971. UnicodeDst[iI].Unicode = awchUnicode[iI];
  972. }
  973. qsort(UnicodeDst, iNumOfHandle, sizeof(WCHAR)+sizeof(WORD), Comp);
  974. for( iI = 0; iI < iNumOfHandle; iI ++ )
  975. {
  976. wchTemp = UnicodeDst[iI].Unicode;
  977. if (wchTemp == EURO_CUR_SYMBOL || wchTemp == 0xFFFF)
  978. {
  979. iNumOfUnsupportChar ++;
  980. UnicodeDst[iI].Unicode = 0;
  981. continue;
  982. }
  983. else
  984. if (wchTemp == wchCurrent + 1)
  985. {
  986. wchCurrent ++;
  987. continue;
  988. }
  989. wchCurrent = wchTemp;
  990. iNumOfRuns ++;
  991. }
  992. //
  993. // Create GLYPHRUN
  994. //
  995. if (bSymbolCharSet)
  996. {
  997. iNumOfRuns ++;
  998. }
  999. if( !(pGlyphRunOrg = pGlyphRun =
  1000. (PGLYPHRUN)MemAlloc( iNumOfRuns * sizeof(GLYPHRUN) )) )
  1001. {
  1002. ERR(("UniFont!NTGTT1To1:MemAlloc failed\n"));
  1003. return NULL;
  1004. }
  1005. wchCurrent = 0;
  1006. for (iI = 0; iI < iNumOfHandle; iI ++)
  1007. {
  1008. wchTemp = UnicodeDst[iI].Unicode;
  1009. if (wchTemp == 0)
  1010. {
  1011. continue;
  1012. }
  1013. else
  1014. if (wchTemp == wchCurrent + 1)
  1015. {
  1016. pGlyphRun->wGlyphCount++;
  1017. wchCurrent ++;
  1018. }
  1019. else
  1020. {
  1021. if (wchCurrent != 0)
  1022. pGlyphRun ++;
  1023. wchCurrent =
  1024. pGlyphRun->wcLow = wchTemp;
  1025. pGlyphRun->wGlyphCount = 1;
  1026. }
  1027. }
  1028. if (bSymbolCharSet)
  1029. {
  1030. pGlyphRun++;
  1031. pGlyphRun->wcLow = SYMBOL_START;
  1032. pGlyphRun->wGlyphCount = NUM_OF_SYMBOL;
  1033. }
  1034. //
  1035. // Calculate total size of this file.
  1036. //
  1037. iNumOfHandle -= iNumOfUnsupportChar;
  1038. iTotalGlyphSetDataSize = sizeof(UNI_GLYPHSETDATA) +
  1039. sizeof(UNI_CODEPAGEINFO) +
  1040. iNumOfRuns * sizeof( GLYPHRUN ) +
  1041. sizeof(MAPTABLE) +
  1042. (iNumOfHandle - 1) * sizeof(TRANSDATA);
  1043. if (bSymbolCharSet)
  1044. {
  1045. iTotalGlyphSetDataSize += sizeof(TRANSDATA) * NUM_OF_SYMBOL;
  1046. }
  1047. //
  1048. // Allocate memory and set header, copy GLYPHRUN, CODEPAGEINFO
  1049. //
  1050. if( !(pbBase = MemAlloc( iTotalGlyphSetDataSize )) )
  1051. {
  1052. MemFree(pGlyphRunOrg);
  1053. return NULL;
  1054. }
  1055. ((PUNI_GLYPHSETDATA)pbBase)->dwVersion = UNI_GLYPHSETDATA_VERSION_1_0;
  1056. ((PUNI_GLYPHSETDATA)pbBase)->dwFlags = 0;
  1057. ((PUNI_GLYPHSETDATA)pbBase)->lPredefinedID = CC_NOPRECNV;
  1058. ((PUNI_GLYPHSETDATA)pbBase)->dwGlyphCount = 0;
  1059. ((PUNI_GLYPHSETDATA)pbBase)->dwCodePageCount = 1;
  1060. ((PUNI_GLYPHSETDATA)pbBase)->dwRunCount = iNumOfRuns;
  1061. ((PUNI_GLYPHSETDATA)pbBase)->dwSize = iTotalGlyphSetDataSize;
  1062. ((PUNI_GLYPHSETDATA)pbBase)->loRunOffset = sizeof(UNI_GLYPHSETDATA);
  1063. ((PUNI_GLYPHSETDATA)pbBase)->loCodePageOffset =
  1064. sizeof(UNI_GLYPHSETDATA) +
  1065. sizeof(GLYPHRUN) * iNumOfRuns;
  1066. ((PUNI_GLYPHSETDATA)pbBase)->loMapTableOffset =
  1067. sizeof(UNI_GLYPHSETDATA) +
  1068. sizeof(GLYPHRUN) * iNumOfRuns +
  1069. sizeof(UNI_CODEPAGEINFO);
  1070. CopyMemory(pbBase + sizeof(UNI_GLYPHSETDATA),
  1071. pGlyphRunOrg,
  1072. sizeof(GLYPHRUN) * iNumOfRuns);
  1073. //
  1074. // CodePageInfo
  1075. //
  1076. pCodePageInfo = (PUNI_CODEPAGEINFO)(pbBase + ((PUNI_GLYPHSETDATA)pbBase)->loCodePageOffset);
  1077. pCodePageInfo->dwCodePage = dwCodePage;
  1078. pCodePageInfo->SelectSymbolSet.dwCount = 0;
  1079. pCodePageInfo->UnSelectSymbolSet.dwCount = 0;
  1080. pCodePageInfo->SelectSymbolSet.loOffset = 0;
  1081. pCodePageInfo->UnSelectSymbolSet.loOffset = 0;
  1082. //
  1083. // MapTable
  1084. //
  1085. pMapTable = (PMAPTABLE)(pbBase +
  1086. ((PUNI_GLYPHSETDATA)pbBase)->loMapTableOffset);
  1087. pMapTable->dwSize = sizeof(MAPTABLE) +
  1088. (iNumOfHandle - 1) * sizeof(TRANSDATA);
  1089. pMapTable->dwGlyphNum = iNumOfHandle;
  1090. pTrans = pMapTable->Trans;
  1091. iIndex = 0;
  1092. iK = 0;
  1093. pGlyphRun = pGlyphRunOrg;
  1094. if (bSymbolCharSet)
  1095. {
  1096. for( iI = 0; iI < iNumOfRuns; iI ++, pGlyphRun ++)
  1097. {
  1098. if (pGlyphRun->wcLow == SYMBOL_START)
  1099. {
  1100. for (iJ = SYMBOL_START; iJ <= SYMBOL_END; iJ ++)
  1101. {
  1102. pTrans[iIndex].ubCodePageID = 0;
  1103. pTrans[iIndex].ubType = MTYPE_DIRECT;
  1104. pTrans[iIndex].uCode.ubCode = (BYTE)iJ;
  1105. iIndex++;
  1106. }
  1107. }
  1108. else
  1109. {
  1110. for( iJ = 0; iJ < pGlyphRun->wGlyphCount; iJ ++)
  1111. {
  1112. while (iK < 256 && UnicodeDst[iK].Unicode == 0)
  1113. {
  1114. iK++;
  1115. }
  1116. if (iK < 256)
  1117. {
  1118. pTrans[iIndex].ubCodePageID = 0;
  1119. pTrans[iIndex].ubType = MTYPE_DIRECT;
  1120. pTrans[iIndex].uCode.ubCode = (BYTE)UnicodeDst[iK++].wID;
  1121. iIndex++;
  1122. }
  1123. }
  1124. }
  1125. }
  1126. }
  1127. else
  1128. {
  1129. for( iI = 0; iI < iNumOfHandle; iI ++)
  1130. {
  1131. while (iK < 256 && UnicodeDst[iK].Unicode == 0)
  1132. {
  1133. iK++;
  1134. }
  1135. if (iK < 256)
  1136. {
  1137. pTrans[iIndex].ubCodePageID = 0;
  1138. pTrans[iIndex].ubType = MTYPE_DIRECT;
  1139. pTrans[iIndex].uCode.ubCode = (BYTE)UnicodeDst[iK++].wID;
  1140. iIndex++;
  1141. }
  1142. }
  1143. }
  1144. MemFree(pGlyphRunOrg);
  1145. VDBGDUMPGTT((PUNI_GLYPHSETDATA)pbBase);
  1146. return (PUNI_GLYPHSETDATA)pbBase;
  1147. }
  1148. BOOL
  1149. BExtractGTTwithPredefGTT(
  1150. IN PUNI_GLYPHSETDATA pPreDefGTT,
  1151. IN PUNI_GLYPHSETDATA pMiniDefGTT,
  1152. IN WCHAR wchFirst,
  1153. IN WCHAR wchLast,
  1154. OUT FD_GLYPHSET **ppFD_GLYPHSET,
  1155. OUT MAPTABLE **ppMapTable,
  1156. IN PDWORD pdwFD_GLYPHSETSize)
  1157. {
  1158. PGLYPHRUN pPreDefGlyphRun, pMiniDefGlyphRun;
  1159. PMAPTABLE pMiniMapTable;
  1160. PTRANSDATA pMiniDefTrans, pPreDefTrans;
  1161. PTRANSDATA pSrcTrans, pDstTrans, pNewTrans, pTrans;
  1162. WCRUN* pWCRun;
  1163. HGLYPH *pHGlyph;
  1164. DWORD dwGlyphNum, dwMapTableSize, dwRunCount, dwIndex, dwI;
  1165. DWORD dwAddGlyphNum, dwSubGlyphNum, dwType;
  1166. WORD wJ;
  1167. WCHAR wcLow, wcHigh;
  1168. BOOL bInRun;
  1169. //
  1170. // FD_GLYPHSET creation.
  1171. //
  1172. // Additonal case:
  1173. // case 1: the begining of predef run
  1174. // Change wcLow and add cGlyphs in WCRUN.
  1175. // Change cGlyphsSupported in FD_GLYPHSET.
  1176. // case 2: the end of predef run
  1177. // Change add cGlyphs in WCRUN.
  1178. // Change cGlyphsSupported in FD_GLYPHSET.
  1179. // case 3: not in the predef run
  1180. // Add new WCRUN
  1181. // Change cGlyphsSupported in FD_GLYPHSET.
  1182. //
  1183. // Disable case:
  1184. // case 1: the begining of predef run
  1185. // Change wcLow and cGlyphs in WCRUN.
  1186. // Change cGlyphsSupported in FD_GLYPHSET.
  1187. // case 2: in the middle of predef run
  1188. // Divide this run into two different run.
  1189. // Change cGlyphsSupported in FD_GLYPHSET.
  1190. // case 3: the end of predef run
  1191. // Change cGlyphs in WCRUN.
  1192. // Change cGlyphsSupported in FD_GLYPHSET.
  1193. //
  1194. // Replace case:
  1195. // Do nothing.
  1196. //
  1197. ASSERT(pPreDefGTT != NULL && pMiniDefGTT);
  1198. //
  1199. // Count glyph number in predefined GTT.
  1200. //
  1201. dwGlyphNum = 0;
  1202. pPreDefGlyphRun = GET_GLYPHRUN(pPreDefGTT);
  1203. for (dwI = 0; dwI < pPreDefGTT->dwRunCount; dwI ++, pPreDefGlyphRun ++)
  1204. {
  1205. dwGlyphNum += pPreDefGlyphRun->wGlyphCount;
  1206. }
  1207. pPreDefGlyphRun = GET_GLYPHRUN(pPreDefGTT);
  1208. pMiniDefGlyphRun = GET_GLYPHRUN(pMiniDefGTT);
  1209. pMiniMapTable = GET_MAPTABLE(pMiniDefGTT);
  1210. dwIndex = 0;
  1211. dwAddGlyphNum = 0;
  1212. dwSubGlyphNum = 0;
  1213. //
  1214. // Count a total glyph number and glyph run number.
  1215. //
  1216. for (dwI = 0; dwI < pMiniDefGTT->dwRunCount; dwI ++, pMiniDefGlyphRun ++)
  1217. {
  1218. wcHigh = pMiniDefGlyphRun->wcLow + pMiniDefGlyphRun->wGlyphCount;
  1219. for (wJ = pMiniDefGlyphRun->wcLow; wJ < wcHigh; wJ ++, dwIndex ++)
  1220. {
  1221. switch (pMiniMapTable->Trans[dwIndex].ubType & MTYPE_PREDEFIN_MASK)
  1222. {
  1223. case MTYPE_ADD:
  1224. dwAddGlyphNum ++;
  1225. break;
  1226. case MTYPE_DISABLE:
  1227. dwSubGlyphNum ++;
  1228. break;
  1229. case MTYPE_REPLACE:
  1230. default:
  1231. break;
  1232. }
  1233. }
  1234. }
  1235. dwGlyphNum += dwAddGlyphNum - dwSubGlyphNum;
  1236. //
  1237. // Create MAPTABLE
  1238. //
  1239. // Memory allocation
  1240. // Creation
  1241. //
  1242. // ----------------
  1243. // Predefined MAPPTABLE (1 -> n glyph handle)
  1244. // Minidriver's MTYPE_DISABLE is already removed.
  1245. // ----------------
  1246. // Minidriver additional MAPTABLE
  1247. // (n + 1 -> n + m) glyph handle
  1248. // Even if some glyphs could be merged into Predefined MAPTABLE, we
  1249. // separate them with minidriver's additional glyphs for a convenience.
  1250. // ----------------
  1251. //
  1252. dwMapTableSize = sizeof(MAPTABLE) + sizeof(TRANSDATA) * (dwGlyphNum - 1);
  1253. if((*ppMapTable = MemAlloc(dwMapTableSize)) == NULL)
  1254. {
  1255. return FALSE;
  1256. }
  1257. //
  1258. // Fill in MAPTABLE
  1259. //
  1260. (*ppMapTable)->dwSize = dwMapTableSize;
  1261. (*ppMapTable)->dwGlyphNum = dwGlyphNum;
  1262. pPreDefGlyphRun = GET_GLYPHRUN(pPreDefGTT);
  1263. pMiniDefGlyphRun = GET_GLYPHRUN(pMiniDefGTT);
  1264. pMiniMapTable = GET_MAPTABLE(pMiniDefGTT);
  1265. pPreDefTrans = (GET_MAPTABLE(pPreDefGTT))->Trans;
  1266. pMiniDefTrans = pMiniMapTable->Trans;
  1267. pTrans = (*ppMapTable)->Trans;
  1268. pNewTrans = (*ppMapTable)->Trans + dwGlyphNum - dwAddGlyphNum;
  1269. dwIndex = 0;
  1270. dwRunCount = 0;
  1271. for (dwI = 0; dwI < pPreDefGlyphRun->wGlyphCount; dwI ++)
  1272. {
  1273. wcHigh = pPreDefGlyphRun->wcLow + pPreDefGlyphRun->wGlyphCount;
  1274. bInRun = FALSE;
  1275. for (wJ = pPreDefGlyphRun->wcLow; wJ < wcHigh; wJ ++)
  1276. {
  1277. dwType = DwCheckTrans(pMiniDefGlyphRun,
  1278. pMiniMapTable,
  1279. pMiniDefGTT->dwRunCount,
  1280. wJ);
  1281. if ( (dwType == 0) || (dwType == MTYPE_REPLACE) )
  1282. {
  1283. if (!bInRun)
  1284. {
  1285. dwRunCount ++;
  1286. bInRun = TRUE;
  1287. }
  1288. if (!dwType )
  1289. {
  1290. pSrcTrans = pPreDefTrans;
  1291. pDstTrans = pTrans;
  1292. }
  1293. else
  1294. if (dwType == MTYPE_REPLACE)
  1295. {
  1296. pSrcTrans = pMiniDefTrans;
  1297. pDstTrans = pTrans;
  1298. }
  1299. pDstTrans->ubCodePageID = pSrcTrans->ubCodePageID;
  1300. pDstTrans->ubType = pSrcTrans->ubType;
  1301. switch(pSrcTrans->ubType & MTYPE_FORMAT_MASK)
  1302. {
  1303. case MTYPE_COMPOSE:
  1304. pDstTrans->uCode.ubCode = pSrcTrans->uCode.ubCode;
  1305. break;
  1306. case MTYPE_DIRECT:
  1307. pDstTrans->uCode.ubPairs[0] = pSrcTrans->uCode.ubPairs[0];
  1308. pDstTrans->uCode.ubPairs[1] = pSrcTrans->uCode.ubPairs[1];
  1309. break;
  1310. case MTYPE_PAIRED:
  1311. pDstTrans->uCode.sCode = pSrcTrans->uCode.sCode;
  1312. break;
  1313. }
  1314. pSrcTrans ++;
  1315. pDstTrans ++;
  1316. }
  1317. else
  1318. if (dwType == MTYPE_DISABLE)
  1319. {
  1320. pPreDefTrans ++;
  1321. if (bInRun && wJ != wcHigh - 1)
  1322. {
  1323. dwRunCount ++;
  1324. bInRun = FALSE;
  1325. }
  1326. }
  1327. }
  1328. }
  1329. for (dwI = 0; dwI < pMiniDefGlyphRun->wGlyphCount; dwI ++)
  1330. {
  1331. wcHigh = pMiniDefGlyphRun->wcLow + pMiniDefGlyphRun->wGlyphCount;
  1332. bInRun = FALSE;
  1333. for (wJ = pMiniDefGlyphRun->wcLow; wJ < wcHigh; wJ ++, pMiniDefTrans ++)
  1334. {
  1335. if (pMiniDefTrans->ubType & MTYPE_ADD)
  1336. {
  1337. pNewTrans->ubCodePageID = pMiniDefTrans->ubCodePageID;
  1338. pNewTrans->ubType = pMiniDefTrans->ubType;
  1339. switch (pNewTrans->ubType & MTYPE_FORMAT_MASK)
  1340. {
  1341. case MTYPE_COMPOSE:
  1342. pNewTrans->uCode.ubCode = pMiniDefTrans->uCode.ubCode;
  1343. break;
  1344. case MTYPE_DIRECT:
  1345. pNewTrans->uCode.ubPairs[0] = pMiniDefTrans->uCode.ubPairs[0];
  1346. pNewTrans->uCode.ubPairs[1] = pMiniDefTrans->uCode.ubPairs[1];
  1347. break;
  1348. case MTYPE_PAIRED:
  1349. pNewTrans->uCode.sCode = pMiniDefTrans->uCode.sCode;
  1350. break;
  1351. }
  1352. pNewTrans ++;
  1353. if (!bInRun)
  1354. {
  1355. dwRunCount ++;
  1356. bInRun = TRUE;
  1357. }
  1358. }
  1359. else
  1360. {
  1361. if (bInRun)
  1362. {
  1363. bInRun = FALSE;
  1364. }
  1365. }
  1366. }
  1367. }
  1368. //
  1369. // Crate FD_GLYPHSET
  1370. //
  1371. // Memory allocation with dwGlyphNum and dwRunCount.
  1372. //
  1373. // -----------------
  1374. // Predefined FD_GLYPHSET
  1375. // -----------------
  1376. // Minidriver additional glyph run
  1377. // ----------------
  1378. //
  1379. //
  1380. // Now we know the number of run. Allocate memory for FD_GLYPHSET.
  1381. //
  1382. *pdwFD_GLYPHSETSize = sizeof(FD_GLYPHSET) +
  1383. sizeof(WCRUN) * dwRunCount +
  1384. sizeof(HGLYPH) * dwGlyphNum;
  1385. if((*ppFD_GLYPHSET = (FD_GLYPHSET*)MemAlloc(*pdwFD_GLYPHSETSize)) == NULL)
  1386. {
  1387. MemFree(*ppMapTable);
  1388. return FALSE;
  1389. }
  1390. (*ppFD_GLYPHSET)->cjThis = *pdwFD_GLYPHSETSize;
  1391. (*ppFD_GLYPHSET)->cGlyphsSupported = *pdwFD_GLYPHSETSize;
  1392. (*ppFD_GLYPHSET)->cRuns = dwRunCount;
  1393. pWCRun = (*ppFD_GLYPHSET)->awcrun;
  1394. pHGlyph = (HGLYPH*)((PBYTE)*ppFD_GLYPHSET +
  1395. sizeof(FD_GLYPHSET) +
  1396. sizeof(WCRUN) * dwRunCount);
  1397. pPreDefGlyphRun = GET_GLYPHRUN(pPreDefGTT);
  1398. pMiniDefGlyphRun = GET_GLYPHRUN(pMiniDefGTT);
  1399. pMiniDefTrans = pMiniMapTable->Trans;
  1400. for (dwI = 1; dwI <= dwGlyphNum; dwI ++, *pHGlyph)
  1401. {
  1402. *pHGlyph = dwI;
  1403. }
  1404. pHGlyph = (HGLYPH*)((PBYTE)*ppFD_GLYPHSET +
  1405. sizeof(FD_GLYPHSET) +
  1406. sizeof(WCRUN) * dwRunCount);
  1407. for (dwI = 0; dwI < pPreDefGlyphRun->wGlyphCount; dwI ++)
  1408. {
  1409. pWCRun->wcLow = wcLow
  1410. = pPreDefGlyphRun->wcLow;
  1411. wcHigh = wcLow + pPreDefGlyphRun->wGlyphCount;
  1412. bInRun = FALSE;
  1413. for (wJ = pPreDefGlyphRun->wcLow; wJ < wcHigh; wJ ++)
  1414. {
  1415. if (MTYPE_DISABLE == DwCheckTrans(pMiniDefGlyphRun,
  1416. pMiniMapTable,
  1417. pMiniDefGTT->dwRunCount,
  1418. wJ))
  1419. {
  1420. if (bInRun)
  1421. {
  1422. pWCRun->cGlyphs = wJ - wcLow + 1;
  1423. pWCRun->phg = pHGlyph;
  1424. pHGlyph += pWCRun->cGlyphs;
  1425. pWCRun ++;
  1426. bInRun = FALSE;
  1427. }
  1428. }
  1429. else
  1430. {
  1431. if (!bInRun)
  1432. {
  1433. pWCRun->wcLow = wcLow
  1434. = wJ;
  1435. wcHigh = wcLow + pPreDefGlyphRun->wGlyphCount;
  1436. bInRun = TRUE;
  1437. }
  1438. }
  1439. }
  1440. pWCRun->cGlyphs = wcHigh - wcLow;
  1441. pWCRun->phg = pHGlyph;
  1442. pWCRun ++;
  1443. }
  1444. bInRun = FALSE;
  1445. for (dwI = 0; dwI < pMiniDefGlyphRun->wGlyphCount; dwI ++)
  1446. {
  1447. for (wJ = pMiniDefGlyphRun->wcLow; wJ < wcHigh; wJ ++, pMiniDefTrans ++)
  1448. {
  1449. if (pMiniDefTrans->ubType & MTYPE_ADD)
  1450. {
  1451. if (!bInRun)
  1452. {
  1453. pWCRun->wcLow = wcLow = wJ;
  1454. bInRun = TRUE;
  1455. }
  1456. }
  1457. else
  1458. {
  1459. if (bInRun)
  1460. {
  1461. pWCRun->cGlyphs = wJ - wcLow + 1;
  1462. pWCRun->phg = pHGlyph;
  1463. pHGlyph += pWCRun->cGlyphs;
  1464. bInRun = FALSE;
  1465. }
  1466. }
  1467. }
  1468. }
  1469. return TRUE;
  1470. }
  1471. DWORD
  1472. DwCheckTrans(
  1473. PGLYPHRUN pMiniGlyphRun,
  1474. PMAPTABLE pMiniMapTable,
  1475. DWORD dwMiniGlyphRunCount,
  1476. WORD wUnicode)
  1477. {
  1478. DWORD dwI;
  1479. WORD wIndex;
  1480. for (dwI = 0; dwI < dwMiniGlyphRunCount; dwI ++, pMiniGlyphRun ++)
  1481. {
  1482. if (wUnicode < pMiniGlyphRun->wcLow)
  1483. {
  1484. continue;
  1485. }
  1486. if (wUnicode < pMiniGlyphRun->wcLow + pMiniGlyphRun->wGlyphCount)
  1487. {
  1488. wIndex = wUnicode - pMiniGlyphRun->wcLow;
  1489. return pMiniMapTable->Trans[wIndex].ubType & MTYPE_PREDEFIN_MASK;
  1490. }
  1491. else
  1492. {
  1493. return 0;
  1494. }
  1495. }
  1496. return 0;
  1497. }
  1498. int __cdecl Comp(const void *elem1, const void *elem2)
  1499. {
  1500. //struct {
  1501. // WORD wID;
  1502. // WCHAR Unicode;
  1503. //} UnicodeDst[256];
  1504. //
  1505. // Compare Unicode in this data structure
  1506. //
  1507. return *((PWORD)elem1+1) - *((PWORD)elem2+1);
  1508. }