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.

928 lines
28 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: nlsconv.c *
  3. * *
  4. * DBCS specific routines *
  5. * *
  6. * Created: 15-Mar-1994 15:56:30 *
  7. * Author: Gerrit van Wingerden [gerritv] *
  8. * *
  9. * Copyright (c) 1994-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. UINT fFontAssocStatus = 0;
  14. BYTE cLowTrailByteSet1 = 0xff;
  15. BYTE cHighTrailByteSet1 = 0x0;
  16. BYTE cLowTrailByteSet2 = 0xff;
  17. BYTE cHighTrailByteSet2 = 0x0;
  18. /******************************Public*Routine******************************\
  19. * *
  20. * DBCS Trailling Byte validate check functions. *
  21. * *
  22. \**************************************************************************/
  23. #define IS_DBCS_TRAIL_BYTE(Char) (\
  24. ((Char >= cLowTrailByteSet1) && (Char <= cHighTrailByteSet1)) \
  25. ||((Char >= cLowTrailByteSet2) && (Char <= cHighTrailByteSet2)) \
  26. )
  27. /**************************************************************************\
  28. * *
  29. * SHIFT-JIS (Japanese) character set : CodePage 932 *
  30. * *
  31. * Valid LeadByte Range | Valid TailByte Range *
  32. * -----------------------+--------------------- *
  33. * From -> To | From -> To *
  34. * - - - - - - - - - - - - - - - - - - - - - - - *
  35. * 0x81 -> 0x9F | 0x40 -> 0xFC *
  36. * 0xE0 -> 0xFC | *
  37. * *
  38. \**************************************************************************/
  39. /**************************************************************************\
  40. * *
  41. * WANSANG (Korean) character set : CodePage 949 *
  42. * *
  43. * Valid LeadByte Range | Valid TailByte Range *
  44. * -----------------------+--------------------- *
  45. * From -> To | From -> To *
  46. * - - - - - - - - - - - - - - - - - - - - - - - *
  47. * 0xA1 -> 0xAC | 0x40 -> 0xFC *
  48. * 0xB0 -> 0xC8 | *
  49. * 0xCA -> 0xFD | *
  50. * *
  51. \**************************************************************************/
  52. /**************************************************************************\
  53. * *
  54. * GB2312 (PRC Chinese) character set : CodePage 936 *
  55. * *
  56. * Valid LeadByte Range | Valid TailByte Range *
  57. * -----------------------+--------------------- *
  58. * From -> To | From -> To *
  59. * - - - - - - - - - - - - - - - - - - - - - - - *
  60. * 0xA1 -> 0xA9 | 0xA1 -> 0xFE *
  61. * 0xB0 -> 0xF7 | *
  62. * *
  63. \**************************************************************************/
  64. /**************************************************************************\
  65. * *
  66. * Big 5 (Taiwan,Hong Kong Chinese) character set : CodePage 950 *
  67. * *
  68. * Valid LeadByte Range | Valid TailByte Range *
  69. * -----------------------+--------------------- *
  70. * From -> To | From -> To *
  71. * - - - - - - - - - - - - - - - - - - - - - - - *
  72. * 0x81 -> 0xFE | 0x40 -> 0x7E *
  73. * | 0xA1 -> 0xFE *
  74. * *
  75. \**************************************************************************/
  76. /******************************Public*Routine******************************\
  77. * vSetCheckDBCSTrailByte()
  78. *
  79. * This function setup function for the DBCS trailling byte validation of
  80. * specified character with specified Fareast codepage.
  81. *
  82. * Thu-15-Feb-1996 11:59:00 -by- Gerrit van Wingerden
  83. * Moved function pointer out of CFONT and into a global variable.
  84. *
  85. * Wed 20-Dec-1994 10:00:00 -by- Hideyuki Nagase [hideyukn]
  86. * Write it.
  87. \**************************************************************************/
  88. VOID vSetCheckDBCSTrailByte(DWORD dwCodePage)
  89. {
  90. switch( dwCodePage )
  91. {
  92. case 932:
  93. cLowTrailByteSet1 = (CHAR) 0x40;
  94. cHighTrailByteSet1 = (CHAR) 0xfc;
  95. cLowTrailByteSet2 = (CHAR) 0x40;
  96. cHighTrailByteSet2 = (CHAR) 0xfc;
  97. break;
  98. case 949:
  99. cLowTrailByteSet1 = (CHAR) 0x40;
  100. cHighTrailByteSet1 = (CHAR) 0xfc;
  101. cLowTrailByteSet2 = (CHAR) 0x40;
  102. cHighTrailByteSet2 = (CHAR) 0xfc;
  103. break;
  104. case 936:
  105. cLowTrailByteSet1 = (CHAR) 0xa1;
  106. cHighTrailByteSet1 = (CHAR) 0xfe;
  107. cLowTrailByteSet2 = (CHAR) 0xa1;
  108. cHighTrailByteSet2 = (CHAR) 0xfe;
  109. break;
  110. case 950:
  111. cLowTrailByteSet1 = (CHAR) 0x40;
  112. cHighTrailByteSet1 = (CHAR) 0x7e;
  113. cLowTrailByteSet2 = (CHAR) 0xa1;
  114. cHighTrailByteSet2 = (CHAR) 0xfe;
  115. break;
  116. default:
  117. cLowTrailByteSet1 = (CHAR) 0xff;
  118. cHighTrailByteSet1 = (CHAR) 0x0;
  119. cLowTrailByteSet2 = (CHAR) 0xff;
  120. cHighTrailByteSet2 = (CHAR) 0x0;
  121. WARNING("GDI32!INVALID DBCS codepage\n");
  122. break;
  123. }
  124. }
  125. /******************************Public*Routine******************************\
  126. * bComputeCharWidthsDBCS
  127. *
  128. * Client side version of GetCharWidth for DBCS fonts
  129. *
  130. * Wed 18-Aug-1993 10:00:00 -by- Gerrit van Wingerden [gerritv]
  131. * Stole it and converted for DBCS use.
  132. *
  133. * Sat 16-Jan-1993 04:27:19 -by- Charles Whitmer [chuckwh]
  134. * Wrote bComputeCharWidths on which this is based.
  135. \**************************************************************************/
  136. BOOL bComputeCharWidthsDBCS
  137. (
  138. CFONT *pcf,
  139. UINT iFirst,
  140. UINT iLast,
  141. ULONG fl,
  142. PVOID pv
  143. )
  144. {
  145. USHORT *ps;
  146. USHORT ausWidths[256];
  147. UINT ii, cc;
  148. if( iLast - iFirst > 0xFF )
  149. {
  150. WARNING("bComputeCharWidthsDBCS iLast - iFirst > 0xFF" );
  151. return(FALSE);
  152. }
  153. if( iLast < iFirst )
  154. {
  155. WARNING("bComputeCharWidthsDBCS iLast < iFirst" );
  156. return(FALSE);
  157. }
  158. // We want to compute the same widths that would be computed if
  159. // vSetUpUnicodeStringx were called with this first and last and then
  160. // GetCharWidthsW was called. The logic may be wierd but I assume it is
  161. // there for Win 3.1J char widths compatability. To do this first fill
  162. // in the plain widths in ausWidths and then do all the neccesary
  163. // computation on them.
  164. if ( gpwcDBCSCharSet[(UCHAR)(iFirst>>8)] == 0xFFFF )
  165. {
  166. for( cc = 0 ; cc <= iLast - iFirst; cc++ )
  167. {
  168. // If this is a legitimate DBCS character then use
  169. // MaxCharInc.
  170. ausWidths[cc] = pcf->wd.sDBCSInc;
  171. }
  172. }
  173. else
  174. {
  175. for( ii = (iFirst & 0x00FF), cc = 0; ii <= (iLast & 0x00FF); cc++, ii++ )
  176. {
  177. // Just treat everything as a single byte unless we
  178. // encounter a DBCS lead byte which we will treat as a
  179. // default character.
  180. if( gpwcDBCSCharSet[ii] == 0xFFFF )
  181. {
  182. ausWidths[cc] = pcf->wd.sDefaultInc;
  183. }
  184. else
  185. {
  186. ausWidths[cc] = pcf->sWidth[ii];
  187. }
  188. }
  189. }
  190. switch (fl & (GCW_INT | GCW_16BIT))
  191. {
  192. case GCW_INT: // Get LONG widths.
  193. {
  194. LONG *pl = (LONG *) pv;
  195. LONG fxOverhang = 0;
  196. // Check for Win 3.1 compatibility.
  197. if (fl & GCW_WIN3)
  198. fxOverhang = pcf->wd.sOverhang;
  199. // Do the trivial no-transform case.
  200. if (bIsOneSixteenthEFLOAT(pcf->efDtoWBaseline))
  201. {
  202. fxOverhang += 8; // To round the final result.
  203. // for (ii=iFirst; ii<=iLast; ii++)
  204. // *pl++ = (pcf->sWidth[ii] + fxOverhang) >> 4;
  205. ps = ausWidths;
  206. ii = iLast - iFirst;
  207. unroll_1:
  208. switch(ii)
  209. {
  210. default:
  211. pl[4] = (ps[4] + fxOverhang) >> 4;
  212. case 3:
  213. pl[3] = (ps[3] + fxOverhang) >> 4;
  214. case 2:
  215. pl[2] = (ps[2] + fxOverhang) >> 4;
  216. case 1:
  217. pl[1] = (ps[1] + fxOverhang) >> 4;
  218. case 0:
  219. pl[0] = (ps[0] + fxOverhang) >> 4;
  220. }
  221. if (ii > 4)
  222. {
  223. ii -= 5;
  224. pl += 5;
  225. ps += 5;
  226. goto unroll_1;
  227. }
  228. return(TRUE);
  229. }
  230. // Otherwise use the back transform.
  231. else
  232. {
  233. for (ii=0; ii<=iLast-iFirst; ii++)
  234. *pl++ = lCvt(pcf->efDtoWBaseline,ausWidths[ii] + fxOverhang);
  235. return(TRUE);
  236. }
  237. }
  238. case GCW_INT+GCW_16BIT: // Get SHORT widths.
  239. {
  240. USHORT *psDst = (USHORT *) pv;
  241. USHORT fsOverhang = 0;
  242. // Check for Win 3.1 compatibility.
  243. if (fl & GCW_WIN3)
  244. fsOverhang = pcf->wd.sOverhang;
  245. // Do the trivial no-transform case.
  246. if (bIsOneSixteenthEFLOAT(pcf->efDtoWBaseline))
  247. {
  248. fsOverhang += 8; // To round the final result.
  249. // for (ii=iFirst; ii<=iLast; ii++)
  250. // *psDst++ = (pcf->sWidth[ii] + fsOverhang) >> 4;
  251. ps = ausWidths;
  252. ii = iLast - iFirst;
  253. unroll_2:
  254. switch(ii)
  255. {
  256. default:
  257. psDst[4] = (ps[4] + fsOverhang) >> 4;
  258. case 3:
  259. psDst[3] = (ps[3] + fsOverhang) >> 4;
  260. case 2:
  261. psDst[2] = (ps[2] + fsOverhang) >> 4;
  262. case 1:
  263. psDst[1] = (ps[1] + fsOverhang) >> 4;
  264. case 0:
  265. psDst[0] = (ps[0] + fsOverhang) >> 4;
  266. }
  267. if (ii > 4)
  268. {
  269. ii -= 5;
  270. psDst += 5;
  271. ps += 5;
  272. goto unroll_2;
  273. }
  274. return(TRUE);
  275. }
  276. // Otherwise use the back transform.
  277. else
  278. {
  279. for (ii=0; ii<=iLast-iFirst; ii++)
  280. {
  281. *psDst++ = (USHORT)
  282. lCvt
  283. (
  284. pcf->efDtoWBaseline,
  285. (LONG) (ausWidths[ii] + fsOverhang)
  286. );
  287. }
  288. return(TRUE);
  289. }
  290. }
  291. case 0: // Get FLOAT widths.
  292. {
  293. LONG *pe = (LONG *) pv; // Cheat to avoid expensive copies.
  294. EFLOAT_S efWidth,efWidthLogical;
  295. for (ii=0; ii<=iLast-iFirst; ii++)
  296. {
  297. vFxToEf((LONG) ausWidths[ii],efWidth);
  298. vMulEFLOAT(efWidthLogical,efWidth,pcf->efDtoWBaseline);
  299. *pe++ = lEfToF(efWidthLogical);
  300. }
  301. return(TRUE);
  302. }
  303. }
  304. RIP("bComputeCharWidths: Don't come here!\n");
  305. return(FALSE);
  306. }
  307. BOOL bIsDBCSString
  308. (
  309. LPCSTR psz,
  310. int cc
  311. )
  312. {
  313. int ii;
  314. BYTE *pc;
  315. pc = (BYTE *) psz;
  316. cc--; // do not go off the edge !
  317. for (ii=0; ii<cc; ii++)
  318. {
  319. // if DBCS lead byte add in DBCS width
  320. if((gpwcDBCSCharSet[pc[ii]] == 0xFFFF)) // is this a DBCS LeadByte
  321. {
  322. return TRUE;
  323. }
  324. }
  325. return FALSE;
  326. }
  327. /******************************Public*Routine******************************\
  328. * bComputeTextExtentDBCS (pldc,pcf,psz,cc,fl,psizl)
  329. *
  330. * A quick function to compute text extents on the client side for DBCS
  331. * fonts.
  332. *
  333. * Tue 17-Aug-1993 10:00:00 -by- Gerrit van Wingerden [gerritv]
  334. * Stole it and converted for DBCS use.
  335. *
  336. * Thu 14-Jan-1993 04:00:57 -by- Charles Whitmer [chuckwh]
  337. * Wrote bComputeTextExtent from which this was stolen.
  338. \**************************************************************************/
  339. BOOL bComputeTextExtentDBCS
  340. (
  341. PDC_ATTR pDcAttr,
  342. CFONT *pcf,
  343. LPCSTR psz,
  344. int cc,
  345. UINT fl,
  346. SIZE *psizl
  347. )
  348. {
  349. LONG fxBasicExtent;
  350. INT lTextExtra,lBreakExtra,cBreak;
  351. INT cChars = 0;
  352. int ii;
  353. BYTE *pc;
  354. FIX fxCharExtra = 0;
  355. FIX fxBreakExtra;
  356. FIX fxExtra = 0;
  357. lTextExtra = pDcAttr->lTextExtra;
  358. lBreakExtra = pDcAttr->lBreakExtra;
  359. cBreak = pDcAttr->cBreak;
  360. pc = (BYTE *) psz;
  361. // Compute the basic extent.
  362. fxBasicExtent = 0;
  363. pc = (BYTE *) psz;
  364. for (ii=0; ii<cc; ii++)
  365. {
  366. // if DBCS lead byte add in DBCS width
  367. if( /* Check the string has two bytes or more ? */
  368. cc - ii - 1 &&
  369. /* Check Is this a DBCS LeadByte ? */
  370. gpwcDBCSCharSet[*pc] == 0xFFFF &&
  371. /* Check Is this a DBCS TrailByte ? */
  372. IS_DBCS_TRAIL_BYTE((*(pc+sizeof(CHAR))))
  373. )
  374. {
  375. ii++;
  376. pc += 2;
  377. fxBasicExtent += pcf->wd.sDBCSInc;
  378. }
  379. else
  380. {
  381. fxBasicExtent += pcf->sWidth[*pc++];
  382. }
  383. cChars += 1;
  384. }
  385. // Adjust for CharExtra.
  386. if (lTextExtra)
  387. {
  388. int cNoBackup = 0;
  389. fxCharExtra = lCvt(pcf->efM11,lTextExtra);
  390. if( fxCharExtra < 0 )
  391. {
  392. // the layout code won't backup a characters past it's origin regardless
  393. // of the value of iTextCharExtra so figure out for how many values
  394. // we will need to ignore fxCharExtra
  395. if( pcf->wd.sCharInc == 0 )
  396. {
  397. for( ii = 0; ii < cc; ii++ )
  398. {
  399. if( gpwcDBCSCharSet[(BYTE)psz[ii]] == 0xFFFF )
  400. {
  401. if( pcf->wd.sDBCSInc + fxCharExtra <= 0 )
  402. {
  403. cNoBackup += 1;
  404. }
  405. ii++;
  406. }
  407. else
  408. {
  409. if( pcf->sWidth[(BYTE)psz[ii]] + fxCharExtra <= 0 )
  410. {
  411. cNoBackup += 1;
  412. }
  413. }
  414. }
  415. }
  416. else
  417. if( pcf->wd.sCharInc + fxCharExtra <= 0 )
  418. {
  419. cNoBackup = cChars;
  420. }
  421. }
  422. if ( (fl & GGTE_WIN3_EXTENT) && (pcf->hdc == 0)
  423. && (!(pcf->flInfo & FM_INFO_TECH_STROKE)) )
  424. fxExtra = fxCharExtra * ((lTextExtra > 0) ? cChars : (cChars - 1));
  425. else
  426. fxExtra = fxCharExtra * ( cChars - cNoBackup );
  427. }
  428. // Adjust for lBreakExtra.
  429. if (lBreakExtra && cBreak)
  430. {
  431. fxBreakExtra = lCvt(pcf->efM11,lBreakExtra) / cBreak;
  432. // Windows won't let us back up over a break. Set up the BreakExtra
  433. // to just cancel out what we've already got.
  434. if (fxBreakExtra + pcf->wd.sBreak + fxCharExtra < 0)
  435. fxBreakExtra = -(pcf->wd.sBreak + fxCharExtra);
  436. // Add it up for all breaks.
  437. pc = (BYTE *) psz;
  438. for (ii=0; ii<cc; ii++)
  439. {
  440. if (gpwcDBCSCharSet[*pc] == 0xFFFF)
  441. {
  442. ii++;
  443. pc += 2;
  444. }
  445. else if (*pc++ == pcf->wd.iBreak)
  446. {
  447. fxExtra += fxBreakExtra;
  448. }
  449. }
  450. }
  451. // Add in the extra stuff.
  452. fxBasicExtent += fxExtra;
  453. // Add in the overhang for font simulations.
  454. if (fl & GGTE_WIN3_EXTENT)
  455. fxBasicExtent += pcf->wd.sOverhang;
  456. // Transform the result to logical coordinates.
  457. if (bIsOneSixteenthEFLOAT(pcf->efDtoWBaseline))
  458. psizl->cx = (fxBasicExtent + 8) >> 4;
  459. else
  460. psizl->cx = lCvt(pcf->efDtoWBaseline,fxBasicExtent);
  461. psizl->cy = pcf->lHeight;
  462. return(TRUE);
  463. }
  464. /******************************Public*Routine*****************************\
  465. * QueryFontAssocStatus() *
  466. * *
  467. * History: *
  468. * 05-Jan-1994 -by- Pi-Sui Hsu [pisuih] *
  469. * Wrote it. *
  470. \*************************************************************************/
  471. UINT APIENTRY QueryFontAssocStatus( VOID )
  472. {
  473. return(fFontAssocStatus);
  474. }
  475. INT APIENTRY GetFontAssocStatus( HDC hdc )
  476. {
  477. if(hdc == NULL)
  478. {
  479. return(0);
  480. }
  481. else
  482. {
  483. return(NtGdiQueryFontAssocInfo(hdc));
  484. }
  485. }
  486. BOOL bToUnicodeNx(LPWSTR pwsz, LPCSTR psz, DWORD c, UINT codepage)
  487. {
  488. if(fFontAssocStatus &&
  489. ((codepage == GetACP() || codepage == CP_ACP)) &&
  490. ((c == 1) || ((c == 2 && *(psz) && *((LPCSTR)(psz + 1)) == '\0'))))
  491. {
  492. //
  493. // If this function is called with only 1 char, and font association
  494. // is enabled, we should forcely convert the chars to Unicode with
  495. // codepage 1252.
  496. // This is for enabling to output Latin-1 chars ( > 0x80 in Ansi codepage )
  497. // Because, normally font association is enabled, we have no way to output
  498. // those charactres, then we provide the way, if user call TextOutA() with
  499. // A character and ansi font, we tempotary disable font association.
  500. // This might be Windows 3.1 (Korean/Taiwanese) version compatibility..
  501. //
  502. codepage = 1252;
  503. }
  504. if(MultiByteToWideChar(codepage, 0, psz, c, pwsz, c))
  505. {
  506. return(TRUE);
  507. }
  508. else
  509. {
  510. GdiSetLastError(ERROR_INVALID_PARAMETER);
  511. return(FALSE);
  512. }
  513. }
  514. /******************************Public*Routine******************************\
  515. *
  516. * vSetUpUnicodeStringx
  517. *
  518. * Effects:
  519. *
  520. * Warnings:
  521. *
  522. * History:
  523. * 14-Mar-1993 -by- Hideyuki Nagase [hideyukn]
  524. * Change hardcoded default character to defulat char is given as a parameter.
  525. *
  526. * 01-Mar-1993 -by- Takao Kitano [takaok]
  527. * Wrote it.
  528. \**************************************************************************/
  529. BOOL bSetUpUnicodeStringDBCS
  530. (
  531. IN UINT iFirst, // first ansi char
  532. IN UINT iLast, // last char
  533. IN PUCHAR puchTmp, // temporary buffer
  534. OUT PWCHAR pwc, // output fuffer with a unicode string
  535. IN UINT uiCodePage, // ansi codepage
  536. IN CHAR chDefaultChar // default character
  537. )
  538. {
  539. PUCHAR puchBuf;
  540. BOOL bRet = FALSE;
  541. puchBuf = puchTmp;
  542. if(IsDBCSLeadByteEx(uiCodePage,(UCHAR)(iFirst >> 8)))
  543. {
  544. // This is DBCS character strings.
  545. for (; iFirst <= iLast; iFirst++ )
  546. {
  547. *puchBuf++ = (UCHAR)(iFirst >> 8);
  548. *puchBuf++ = (UCHAR)(iFirst);
  549. }
  550. }
  551. else
  552. {
  553. // This is SBCS character strings.
  554. // if Hi-byte of iFirst is not valid DBCS LeadByte , we use only
  555. // lo-byte of it.
  556. for ( ; iFirst <= iLast; iFirst++ )
  557. {
  558. // If this SBCS code in LeadByte area . It replce with default
  559. // character
  560. if ( IsDBCSLeadByteEx(uiCodePage,(UCHAR)iFirst) )
  561. *puchBuf++ = chDefaultChar;
  562. else
  563. *puchBuf++ = (UCHAR)iFirst;
  564. }
  565. }
  566. //Sundown: safe to truncate to DWORD since puchBug - puchTmp won't exceed iLast
  567. bRet = bToUnicodeNx(pwc, puchTmp, (DWORD)(puchBuf - puchTmp), uiCodePage);
  568. return(bRet);
  569. }
  570. BOOL IsValidDBCSRange( UINT iFirst , UINT iLast )
  571. {
  572. // DBCS & SBCS char parameter checking for DBCS font
  573. if( iFirst > 0x00ff )
  574. {
  575. // DBCS char checking for DBCS font
  576. if (
  577. // Check limit
  578. (iFirst > 0xffff) || (iLast > 0xffff) ||
  579. // DBCSLeadByte shoud be same
  580. (iFirst & 0xff00) != (iLast & 0xff00) ||
  581. // DBCSTrailByte of the First should be >= one of the Last
  582. (iFirst & 0x00ff) > (iLast & 0x00ff)
  583. )
  584. {
  585. return(FALSE);
  586. }
  587. }
  588. // DBCS char checking for DBCS font
  589. else if( (iFirst > iLast) || (iLast & 0xffffff00) )
  590. {
  591. return(FALSE);
  592. }
  593. return(TRUE);
  594. }
  595. /******************************Private*Routine*****************************\
  596. * GetCurrentDefaultChar()
  597. *
  598. * History:
  599. *
  600. * Mon 15-Mar-1993 18:14:00 -by- Hideyuki Nagase
  601. * wrote it.
  602. ***************************************************************************/
  603. BYTE GetCurrentDefaultChar(HDC hdc)
  604. {
  605. // WINBUG 365031 4-10-2001 pravins Consider optimization in GetCurrentDeafultChar
  606. //
  607. // Old Comment:
  608. // - This is slow for now. We should cache this value locally in the dcattr
  609. // but want to get other things working for now. [gerritv] 2-22-96
  610. TEXTMETRICA tma;
  611. GetTextMetricsA( hdc , &tma );
  612. return(tma.tmDefaultChar);
  613. }
  614. /***************************************************************************
  615. * ConvertDxArray(UINT, char*, INT*, UINT, INT*)
  616. *
  617. * Tue 27-Feb-1996 23:45:00 -by- Gerrit van Wingerden [gerritv]
  618. *
  619. ***************************************************************************/
  620. void ConvertDxArray(UINT CodePage,
  621. char *pDBCSString,
  622. INT *pDxDBCS,
  623. UINT Count,
  624. INT *pDxUnicode,
  625. BOOL bPdy
  626. )
  627. {
  628. char *pDBCSStringEnd;
  629. if (!bPdy)
  630. {
  631. for(pDBCSStringEnd = pDBCSString + Count;
  632. pDBCSString < pDBCSStringEnd;
  633. )
  634. {
  635. if(IsDBCSLeadByteEx(CodePage,*pDBCSString))
  636. {
  637. pDBCSString += 2;
  638. *pDxUnicode = *pDxDBCS++;
  639. *pDxUnicode += *pDxDBCS++;
  640. }
  641. else
  642. {
  643. pDBCSString += 1;
  644. *pDxUnicode = *pDxDBCS++;
  645. }
  646. pDxUnicode += 1;
  647. }
  648. }
  649. else
  650. {
  651. POINTL *pdxdyUnicode = (POINTL *)pDxUnicode;
  652. POINTL *pdxdyDBCS = (POINTL *)pDxDBCS;
  653. for(pDBCSStringEnd = pDBCSString + Count;
  654. pDBCSString < pDBCSStringEnd;
  655. )
  656. {
  657. if(IsDBCSLeadByteEx(CodePage,*pDBCSString))
  658. {
  659. pDBCSString += 2;
  660. *pdxdyUnicode = *pdxdyDBCS++;
  661. pdxdyUnicode->x += pdxdyDBCS->x;
  662. pdxdyUnicode->y += pdxdyDBCS->y;
  663. pdxdyDBCS++;
  664. }
  665. else
  666. {
  667. pDBCSString += 1;
  668. *pdxdyUnicode = *pdxdyDBCS++;
  669. }
  670. pdxdyUnicode++;
  671. }
  672. }
  673. }
  674. ULONG APIENTRY EudcLoadLinkW
  675. (
  676. LPCWSTR pBaseFaceName,
  677. LPCWSTR pEudcFontPath,
  678. INT iPriority,
  679. INT iFontLinkType
  680. )
  681. {
  682. return(NtGdiEudcLoadUnloadLink(pBaseFaceName,
  683. (pBaseFaceName) ? wcslen(pBaseFaceName) : 0,
  684. pEudcFontPath,
  685. wcslen(pEudcFontPath),
  686. iPriority,
  687. iFontLinkType,
  688. TRUE));
  689. }
  690. BOOL APIENTRY EudcUnloadLinkW
  691. (
  692. LPCWSTR pBaseFaceName,
  693. LPCWSTR pEudcFontPath
  694. )
  695. {
  696. return(NtGdiEudcLoadUnloadLink(pBaseFaceName,
  697. (pBaseFaceName) ? wcslen(pBaseFaceName) : 0,
  698. pEudcFontPath,
  699. wcslen(pEudcFontPath),
  700. 0,
  701. 0,
  702. FALSE));
  703. }
  704. ULONG APIENTRY GetEUDCTimeStampExW
  705. (
  706. LPCWSTR pBaseFaceName
  707. )
  708. {
  709. return(NtGdiGetEudcTimeStampEx((LPWSTR) pBaseFaceName,
  710. (pBaseFaceName) ? wcslen(pBaseFaceName) : 0,
  711. FALSE));
  712. }
  713. ULONG APIENTRY GetEUDCTimeStamp()
  714. {
  715. return(NtGdiGetEudcTimeStampEx(NULL,0,TRUE));
  716. }
  717. UINT
  718. GetStringBitmapW(
  719. HDC hdc,
  720. LPWSTR pwc,
  721. UINT cwc,
  722. UINT cbData,
  723. BYTE *pSB
  724. )
  725. {
  726. if(cwc != 1)
  727. {
  728. return(0);
  729. }
  730. return(NtGdiGetStringBitmapW(hdc,pwc,1,(PBYTE) pSB,cbData));
  731. }
  732. UINT
  733. GetStringBitmapA(
  734. HDC hdc,
  735. LPSTR pc,
  736. UINT cch,
  737. UINT cbData,
  738. BYTE *pSB
  739. )
  740. {
  741. WCHAR Character[2];
  742. if(cch > 2 )
  743. {
  744. return(0);
  745. }
  746. if(MultiByteToWideChar(CP_ACP,0,pc,cch,Character,2)!=1)
  747. {
  748. return(0);
  749. }
  750. return(GetStringBitmapW(hdc,Character,1,cbData,pSB));
  751. }
  752. DWORD FontAssocHack(DWORD dwCodePage, CHAR *psz, UINT c)
  753. {
  754. // If a Text function is called with only 1 char, and font association
  755. // is enabled, we should forcely convert the chars to Unicode with
  756. // codepage 1252.
  757. // This is for enabling to output Latin-1 chars ( > 0x80 in Ansi codepage )
  758. // Because, normally font association is enabled, we have no way to output
  759. // those charactres, then we provide the way, if user call TextOutA() with
  760. // A character and ansi font, we tempotary disable font association.
  761. // This might be Windows 3.1 (Korean/Taiwanese) version compatibility..
  762. ASSERTGDI(fFontAssocStatus,
  763. "FontAssocHack called with FontAssocStatus turned off\n");
  764. if(((dwCodePage == GetACP() || dwCodePage == CP_ACP)) &&
  765. ((c == 1) || ((c == 2 && *(psz) && *((LPCSTR)(psz + 1)) == '\0'))))
  766. {
  767. return(1252);
  768. }
  769. else
  770. {
  771. return(dwCodePage);
  772. }
  773. }