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.

373 lines
14 KiB

  1. #ifndef WIN32_LEAN_AND_MEAN
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include "exgdiw.h"
  7. #define ExMemAlloc(a) GlobalAllocPtr(GHND, (a))
  8. #define ExMemFree(a) GlobalFreePtr((a))
  9. static POSVERSIONINFO ExGetOSVersion(VOID)
  10. {
  11. static BOOL fFirst = TRUE;
  12. static OSVERSIONINFO os;
  13. if ( fFirst ) {
  14. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  15. if (GetVersionEx( &os ) ) {
  16. fFirst = FALSE;
  17. }
  18. }
  19. return &os;
  20. }
  21. static BOOL ExIsWin95(VOID)
  22. {
  23. BOOL fBool;
  24. fBool = (ExGetOSVersion()->dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
  25. (ExGetOSVersion()->dwMajorVersion >= 4) &&
  26. (ExGetOSVersion()->dwMinorVersion < 10);
  27. return fBool;
  28. }
  29. #if 0
  30. static BOOL ExIsWin98(VOID)
  31. {
  32. BOOL fBool;
  33. fBool = (ExGetOSVersion()->dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
  34. (ExGetOSVersion()->dwMajorVersion >= 4) &&
  35. (ExGetOSVersion()->dwMinorVersion >= 10);
  36. return fBool;
  37. }
  38. static BOOL ExIsWinNT4(VOID)
  39. {
  40. BOOL fBool;
  41. fBool = (ExGetOSVersion()->dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  42. (ExGetOSVersion()->dwMajorVersion >= 4) &&
  43. (ExGetOSVersion()->dwMinorVersion >= 0);
  44. return fBool;
  45. }
  46. static BOOL ExIsWinNT5(VOID)
  47. {
  48. BOOL fBool;
  49. fBool = (ExGetOSVersion()->dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  50. (ExGetOSVersion()->dwMajorVersion >= 4) &&
  51. (ExGetOSVersion()->dwMinorVersion >= 10);
  52. return fBool;
  53. }
  54. static BOOL ExIsWinNT(VOID)
  55. {
  56. BOOL fBool;
  57. fBool = (ExGetOSVersion()->dwPlatformId == VER_PLATFORM_WIN32_NT);
  58. return fBool;
  59. }
  60. #endif
  61. //inline static UINT W2MForWin95(HDC hDC, LPWSTR lpwstr, UINT wchCount,
  62. // LPSTR lpstr, UINT chByteSize)
  63. static UINT W2MForGDI(INT codePage,
  64. LPWSTR lpwstr,
  65. UINT wchCount,
  66. LPSTR lpstr,
  67. UINT chByteSize)
  68. {
  69. LPSTR lptmp;
  70. UINT byte;
  71. UINT mbyte;
  72. char defChar = 0x7F;
  73. BOOL fUseDefChar = TRUE;
  74. switch(codePage) {
  75. case 932:
  76. case 936:
  77. case 950:
  78. case 949:
  79. byte = ::WideCharToMultiByte(codePage, WC_COMPOSITECHECK,
  80. lpwstr, wchCount,
  81. lpstr, chByteSize,
  82. &defChar, NULL);
  83. return byte;
  84. default:
  85. lptmp = lpstr;
  86. for(byte = 0; byte< wchCount; byte++) {
  87. defChar = 0x7F;
  88. mbyte = ::WideCharToMultiByte(codePage, WC_COMPOSITECHECK,
  89. lpwstr,1,
  90. lptmp, chByteSize - byte,
  91. &defChar,
  92. &fUseDefChar);
  93. if(mbyte != 1){
  94. *lptmp = 0x7F; //defChar;
  95. }
  96. lptmp++;
  97. lpwstr++;
  98. }
  99. lpstr[byte]=0x00;
  100. return byte;
  101. }
  102. }
  103. static BOOL _ExExtTextOutWWithTrans(INT codePage,
  104. HDC hdc,
  105. int X,
  106. int Y,
  107. UINT fuOptions,
  108. CONST RECT *lprc,
  109. LPWSTR lpString,
  110. UINT cbCount,
  111. CONST INT *lpDx)
  112. {
  113. #ifndef UNDER_CE // always Unicode
  114. UINT bufsize = (cbCount + 1) * sizeof(WCHAR);
  115. BOOL fRet;
  116. LPSTR lpstr = (LPSTR)ExMemAlloc(bufsize);
  117. if(!lpstr) {
  118. return 0;
  119. }
  120. #if 0
  121. UINT byte = ::WideCharToMultiByte(codePage,
  122. WC_COMPOSITECHECK,
  123. lpString, cbCount,
  124. lpstr, bufsize, &defChar, 0);
  125. #endif
  126. UINT byte = W2MForGDI(codePage, lpString, cbCount, lpstr, bufsize);
  127. fRet = ::ExtTextOutA(hdc,X,Y,fuOptions,lprc,lpstr, byte,lpDx);
  128. ExMemFree(lpstr);
  129. return fRet;
  130. #else // UNDER_CE
  131. return ::ExtTextOutW(hdc,X,Y,fuOptions,lprc,lpString, cbCount,lpDx);
  132. #endif // UNDER_CE
  133. }
  134. //////////////////////////////////////////////////////////////////
  135. // Function : ExExtTextOutWForWin95
  136. // Type : BOOL
  137. // Purpose :
  138. // Args :
  139. // : HDC hdc // handle to device context.
  140. // : int X // x-coordinate of reference point
  141. // : int Y // y-coordinate of reference point
  142. // : UINT fuOptions // text-output options.
  143. // : CONST RECT * lprc // optional clipping and/or opaquing rectangle.
  144. // :
  145. // : LPWSTR lpString // points to string.
  146. // : UINT cbCount // number of characters in string.
  147. // : CONST INT * lpDx // pointer to array of intercharacter spacing values
  148. // Return :
  149. // DATE :
  150. //////////////////////////////////////////////////////////////////
  151. static BOOL ExExtTextOutWForWin95(HDC hdc,
  152. int X,
  153. int Y,
  154. UINT fuOptions,
  155. CONST RECT *lprc,
  156. LPWSTR lpString,
  157. UINT cbCount,
  158. CONST INT *lpDx)
  159. {
  160. //UINT bufsize = (cbCount + 1) * sizeof(WCHAR);
  161. TEXTMETRIC tm;
  162. ::GetTextMetrics(hdc, &tm);
  163. //----------------------------------------------------------------
  164. //980730:By ToshiaK
  165. //Unicode GDI in Win95 has Bugs.
  166. //1. if try to use ExtTextOutW() with FE Unicode code point, with
  167. // som ANSI or SYMBOL charset font, GPF occurs.
  168. //2. ExtTextOutW() cannot draw EUDC code. (Must use ExtTextOutA() to draw)
  169. //----------------------------------------------------------------
  170. LANGID langId = ::GetSystemDefaultLangID();
  171. switch(tm.tmCharSet) {
  172. case SHIFTJIS_CHARSET:
  173. if(PRIMARYLANGID(langId) == LANG_JAPANESE) {
  174. return _ExExtTextOutWWithTrans(932,
  175. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  176. }
  177. return ::ExtTextOutW(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  178. break;
  179. case GB2312_CHARSET:
  180. if(langId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)) {
  181. return _ExExtTextOutWWithTrans(936,
  182. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  183. }
  184. return ::ExtTextOutW(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  185. break;
  186. case CHINESEBIG5_CHARSET:
  187. if(langId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)) {
  188. return _ExExtTextOutWWithTrans(950,
  189. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  190. }
  191. return ::ExtTextOutW(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  192. break;
  193. case HANGEUL_CHARSET:
  194. if(PRIMARYLANGID(langId) == LANG_KOREAN) {
  195. return _ExExtTextOutWWithTrans(949,
  196. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  197. }
  198. return ::ExtTextOutW(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  199. break;
  200. case SYMBOL_CHARSET:
  201. return _ExExtTextOutWWithTrans(1252,
  202. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  203. break;
  204. default:
  205. {
  206. CHARSETINFO info;
  207. if(::TranslateCharsetInfo((DWORD *)tm.tmCharSet,
  208. &info,
  209. TCI_SRCCHARSET)) {
  210. return _ExExtTextOutWWithTrans(info.ciACP,
  211. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  212. }
  213. else {
  214. return _ExExtTextOutWWithTrans(CP_ACP,
  215. hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
  216. }
  217. }
  218. }
  219. }
  220. static BOOL _ExGetTextExtentPoint32WWithTrans(INT codePage,
  221. HDC hdc,
  222. LPWSTR wz,
  223. int cch,
  224. LPSIZE lpSize)
  225. {
  226. #ifndef UNDER_CE // always Unicode
  227. UINT bufsize = (cch + 1) * sizeof(WCHAR);
  228. LPSTR lpstr = (LPSTR)ExMemAlloc(bufsize);
  229. BOOL fRet;
  230. //CHAR defChar = 0x7F;
  231. if(!lpstr) {
  232. return 0;
  233. }
  234. UINT byte = W2MForGDI(codePage, wz, cch, lpstr, bufsize);
  235. #if 0
  236. UINT byte = ::WideCharToMultiByte(codePage,
  237. WC_COMPOSITECHECK,
  238. wz, cch,
  239. lpstr, bufsize,
  240. &defChar, 0);
  241. #endif
  242. fRet = ::GetTextExtentPoint32A(hdc, lpstr, byte, lpSize);
  243. ExMemFree(lpstr);
  244. return fRet;
  245. #else // UNDER_CE
  246. return ::GetTextExtentPoint32W(hdc, wz, cch, lpSize);
  247. #endif // UNDER_CE
  248. }
  249. //////////////////////////////////////////////////////////////////
  250. // Function : ExGetTextExtentPoint32WForWin95
  251. // Type : inline BOOL
  252. // Purpose :
  253. // Args :
  254. // : HDC hdc //handle of device context.
  255. // : LPWSTR wz //address of text string.
  256. // : int cch //number of characters in string.
  257. // : LPSIZE lpSize //address of structure for string size.
  258. // Return :
  259. // DATE : Thu Jul 30 20:31:05 1998
  260. // Histroy :
  261. //////////////////////////////////////////////////////////////////
  262. static BOOL ExGetTextExtentPoint32WForWin95(HDC hdc,
  263. LPWSTR wz,
  264. int cch,
  265. LPSIZE lpSize)
  266. {
  267. TEXTMETRIC tm;
  268. ::GetTextMetrics(hdc, &tm);
  269. LANGID langId = ::GetSystemDefaultLangID();
  270. switch(tm.tmCharSet) {
  271. case SHIFTJIS_CHARSET:
  272. if(PRIMARYLANGID(langId) == LANG_JAPANESE) {
  273. return _ExGetTextExtentPoint32WWithTrans(932, hdc, wz, cch,lpSize);
  274. }
  275. return ::GetTextExtentPoint32W(hdc, wz, cch, lpSize);
  276. break;
  277. case GB2312_CHARSET:
  278. if(langId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)) {
  279. return _ExGetTextExtentPoint32WWithTrans(936, hdc, wz, cch,lpSize);
  280. }
  281. return ::GetTextExtentPoint32W(hdc, wz, cch, lpSize);
  282. break;
  283. case CHINESEBIG5_CHARSET:
  284. if(langId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)) {
  285. return _ExGetTextExtentPoint32WWithTrans(950, hdc, wz, cch,lpSize);
  286. }
  287. return ::GetTextExtentPoint32W(hdc, wz, cch, lpSize);
  288. break;
  289. case HANGEUL_CHARSET:
  290. if(PRIMARYLANGID(langId) == LANG_KOREAN) {
  291. return _ExGetTextExtentPoint32WWithTrans(949, hdc, wz, cch,lpSize);
  292. }
  293. return ::GetTextExtentPoint32W(hdc, wz, cch, lpSize);
  294. break;
  295. case SYMBOL_CHARSET:
  296. return _ExGetTextExtentPoint32WWithTrans(1252, hdc, wz, cch,lpSize);
  297. break;
  298. default:
  299. {
  300. CHARSETINFO info;
  301. if(::TranslateCharsetInfo((DWORD *)tm.tmCharSet, &info, TCI_SRCCHARSET)) {
  302. return _ExGetTextExtentPoint32WWithTrans(info.ciACP, hdc, wz, cch,lpSize);
  303. }
  304. else {
  305. return _ExGetTextExtentPoint32WWithTrans(CP_ACP, hdc, wz, cch,lpSize);
  306. }
  307. }
  308. break;
  309. }
  310. }
  311. //----------------------------------------------------------------
  312. //public Function
  313. //----------------------------------------------------------------
  314. BOOL ExExtTextOutW(HDC hdc, // handle to device context.
  315. int X, // x-coordinate of reference point
  316. int Y, // y-coordinate of reference point
  317. UINT fuOptions, // text-output options.
  318. CONST RECT *lprc, // optional clipping and/or opaquing rectangle.
  319. LPWSTR lpString, // points to string.
  320. UINT cbCount, // number of characters in string.
  321. CONST INT *lpDx) // pointer to array of intercharacter spacing values );
  322. {
  323. if(ExIsWin95()) {
  324. return ExExtTextOutWForWin95(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
  325. }
  326. return ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
  327. }
  328. BOOL ExGetTextExtentPoint32W(HDC hdc, // handle of device context.
  329. LPWSTR wz, // address of text string.
  330. int cch, // number of characters in string.
  331. LPSIZE lpSize) // address of structure for string size.
  332. {
  333. BOOL fRet;
  334. //if char count is 0
  335. if(!wz) {
  336. lpSize->cx = lpSize->cy = 0;
  337. return 0;
  338. }
  339. if(cch == 0) {
  340. #ifndef UNDER_CE
  341. fRet = GetTextExtentPointA(hdc, " ", 1, lpSize);
  342. #else // UNDER_CE
  343. fRet = GetTextExtentPoint(hdc, TEXT(" "), 1, lpSize);
  344. #endif // UNDER_CE
  345. lpSize->cx = 0;
  346. return (fRet);
  347. }
  348. if(ExIsWin95()) {
  349. return ExGetTextExtentPoint32WForWin95(hdc, wz, cch, lpSize);
  350. }
  351. return GetTextExtentPoint32W(hdc, wz, cch, lpSize);
  352. }