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.

6393 lines
259 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: aatext.cxx *
  3. * *
  4. * Routines for rendering anti aliased text to dib surfaces *
  5. * *
  6. * Created: 13-Mar-1995 10:44:05 *
  7. * Author: Kirk Olynyk [kirko] *
  8. * *
  9. * Copyright (c) 1995-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. // Function prototypes
  13. typedef VOID (FNCOPYALPHABUFFER)(PBYTE, PBYTE, PBYTE, LONG, PUSHORT *);
  14. typedef VOID (FNSRCTRANCOPY)(PBYTE, LONG, LONG, PBYTE, LONG, LONG, LONG, LONG,
  15. ULONG, ULONG, SURFACE*, FNCOPYALPHABUFFER*);
  16. extern HSEMAPHORE ghsemEUDC2;
  17. extern "C" {
  18. VOID vSrcTranCopyS4D16(
  19. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  20. VOID vSrcTranCopyS4D24(
  21. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  22. VOID vSrcTranCopyS4D32(
  23. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  24. VOID vSrcOpaqCopyS4D32(
  25. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  26. VOID vSrcOpaqCopyS4D16(
  27. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  28. VOID vSrcOpaqCopyS4D24(
  29. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  30. VOID vSrcOpaqCopyS8D16(
  31. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  32. VOID vSrcOpaqCopyS8D24(
  33. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  34. VOID vSrcOpaqCopyS8D32(
  35. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  36. VOID vSrcTranCopyS8D16(
  37. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  38. VOID vSrcTranCopyS8D24(
  39. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  40. VOID vSrcTranCopyS8D32(
  41. BYTE*,LONG,LONG,BYTE*,LONG,LONG,LONG,LONG,ULONG,ULONG,SURFACE*);
  42. }
  43. // blend macros for cleartype
  44. #define DIVIDE(A,B) ( ((A)+(B)/2) / (B) )
  45. // blend macros for cleartype
  46. // this is k/6, k = 0,1,...,6 in 12.20 format
  47. // Why 12.20 ? well, we are tring to store 6*256 = 1536 = 600h.
  48. // (the largest possible result of multiplying k*dB),
  49. // this fits in eleven bits, so just to be safe we allow 12 bits for
  50. // integer part and 20 bits for the fractional part.
  51. // By using this we avoid doing divides by 6 in trasparent cases and
  52. // in computation of ct lookup table
  53. LONG alAlpha[7] =
  54. {
  55. 0,
  56. DIVIDE(1L << 20, 6),
  57. DIVIDE(2L << 20, 6),
  58. DIVIDE(3L << 20, 6),
  59. DIVIDE(4L << 20, 6),
  60. DIVIDE(5L << 20, 6),
  61. DIVIDE(6L << 20, 6),
  62. };
  63. #define HALF20 (1L << 19)
  64. #define ROUND20(X) (((X) + HALF20) >> 20)
  65. //#define ROUND20(X) ((X) >> 20)
  66. #define BLEND(k,B,dB) ((B) + ROUND20(alAlpha[k] * (dB)))
  67. #define BLENDCT(k,F,B,dB) (ULONG)(BLEND(k,B,dB))
  68. // my test program has determined that regardless of whether we do
  69. // proper rounding in ROUND20 or not, we never arrive at a color that is
  70. // diffent by more than 1 from the value computed the old way
  71. // that is using the old formula:
  72. //
  73. // #define BLEND(k,F,B) (ULONG)DIVIDE((k) * (F) + (6 - (k)) * (B), 6)
  74. //
  75. // the only difference is that if we do rounding, we are wrong in only 2%
  76. // of the cases, and if we do not do rounding we are wrong in 38% of the cases.
  77. // But in either case error is very small.
  78. // Because this is done on a per pixel basis in transparent case, we opt for speed
  79. // and do not do rounding. This saves us 3 additions per pixel.
  80. // John Platt has determined that there are 115 distinct filtered states
  81. // when one starts with (2+2+2)x X 1y scaling for cleartype
  82. #define CT_LOOKUP 115
  83. // filtered counts of RGB
  84. typedef struct _F_RGB
  85. {
  86. BYTE kR;
  87. BYTE kG;
  88. BYTE kB;
  89. BYTE kPadding;
  90. } F_RGB;
  91. // the max number of foreground virt pixels in a subpixel, 2x X 1y , no filtering
  92. #define CT_SAMPLE_NF 2
  93. // the number of distinct nonfiltered states in a whole pixel = 3 x 3 x 3 = 27
  94. // The indices coming from the rasterizer are in [0,26] range
  95. #define CT_MAX_NF ((CT_SAMPLE_NF+1) * (CT_SAMPLE_NF+1) * (CT_SAMPLE_NF+1))
  96. // the max number of foreground virt pixels in a subpixel AFTER filtering, 6
  97. #define CT_SAMPLE_F 6
  98. // size of the storage table, basically 3^5 = 243.
  99. // The table does filtering and index computation (vector quantization) in one step.
  100. #define CT_STORAGE ((CT_SAMPLE_NF+1) * (CT_SAMPLE_NF+1) * (CT_SAMPLE_NF+1) * (CT_SAMPLE_NF+1) * (CT_SAMPLE_NF+1))
  101. // The codebook: 115 entries stored as sequential triples of unsigned char
  102. static const F_RGB gaOutTableRGB[CT_LOOKUP] = {
  103. 0,0,0,0,
  104. 0,0,1,0,
  105. 0,0,2,0,
  106. 0,1,1,0,
  107. 0,1,2,0,
  108. 0,1,3,0,
  109. 0,2,2,0,
  110. 0,2,3,0,
  111. 0,2,4,0,
  112. 1,0,0,0,
  113. 1,0,1,0,
  114. 1,0,2,0,
  115. 1,1,0,0,
  116. 1,1,1,0,
  117. 1,1,2,0,
  118. 1,1,3,0,
  119. 1,2,1,0,
  120. 1,2,2,0,
  121. 1,2,3,0,
  122. 1,2,4,0,
  123. 1,3,2,0,
  124. 1,3,3,0,
  125. 1,3,4,0,
  126. 1,3,5,0,
  127. 2,0,0,0,
  128. 2,0,1,0,
  129. 2,0,2,0,
  130. 2,1,0,0,
  131. 2,1,1,0,
  132. 2,1,2,0,
  133. 2,1,3,0,
  134. 2,2,0,0,
  135. 2,2,1,0,
  136. 2,2,2,0,
  137. 2,2,3,0,
  138. 2,2,4,0,
  139. 2,3,1,0,
  140. 2,3,2,0,
  141. 2,3,3,0,
  142. 2,3,4,0,
  143. 2,3,5,0,
  144. 2,4,2,0,
  145. 2,4,3,0,
  146. 2,4,4,0,
  147. 2,4,5,0,
  148. 2,4,6,0,
  149. 3,1,0,0,
  150. 3,1,1,0,
  151. 3,1,2,0,
  152. 3,1,3,0,
  153. 3,2,0,0,
  154. 3,2,1,0,
  155. 3,2,2,0,
  156. 3,2,3,0,
  157. 3,2,4,0,
  158. 3,3,1,0,
  159. 3,3,2,0,
  160. 3,3,3,0,
  161. 3,3,4,0,
  162. 3,3,5,0,
  163. 3,4,2,0,
  164. 3,4,3,0,
  165. 3,4,4,0,
  166. 3,4,5,0,
  167. 3,4,6,0,
  168. 3,5,3,0,
  169. 3,5,4,0,
  170. 3,5,5,0,
  171. 3,5,6,0,
  172. 4,2,0,0,
  173. 4,2,1,0,
  174. 4,2,2,0,
  175. 4,2,3,0,
  176. 4,2,4,0,
  177. 4,3,1,0,
  178. 4,3,2,0,
  179. 4,3,3,0,
  180. 4,3,4,0,
  181. 4,3,5,0,
  182. 4,4,2,0,
  183. 4,4,3,0,
  184. 4,4,4,0,
  185. 4,4,5,0,
  186. 4,4,6,0,
  187. 4,5,3,0,
  188. 4,5,4,0,
  189. 4,5,5,0,
  190. 4,5,6,0,
  191. 4,6,4,0,
  192. 4,6,5,0,
  193. 4,6,6,0,
  194. 5,3,1,0,
  195. 5,3,2,0,
  196. 5,3,3,0,
  197. 5,3,4,0,
  198. 5,4,2,0,
  199. 5,4,3,0,
  200. 5,4,4,0,
  201. 5,4,5,0,
  202. 5,5,3,0,
  203. 5,5,4,0,
  204. 5,5,5,0,
  205. 5,5,6,0,
  206. 5,6,4,0,
  207. 5,6,5,0,
  208. 5,6,6,0,
  209. 6,4,2,0,
  210. 6,4,3,0,
  211. 6,4,4,0,
  212. 6,5,3,0,
  213. 6,5,4,0,
  214. 6,5,5,0,
  215. 6,6,4,0,
  216. 6,6,5,0,
  217. 6,6,6,0
  218. };
  219. static const F_RGB gaOutTableBGR[CT_LOOKUP] = {
  220. 0,0,0,0,
  221. 1,0,0,0,
  222. 2,0,0,0,
  223. 1,1,0,0,
  224. 2,1,0,0,
  225. 3,1,0,0,
  226. 2,2,0,0,
  227. 3,2,0,0,
  228. 4,2,0,0,
  229. 0,0,1,0,
  230. 1,0,1,0,
  231. 2,0,1,0,
  232. 0,1,1,0,
  233. 1,1,1,0,
  234. 2,1,1,0,
  235. 3,1,1,0,
  236. 1,2,1,0,
  237. 2,2,1,0,
  238. 3,2,1,0,
  239. 4,2,1,0,
  240. 2,3,1,0,
  241. 3,3,1,0,
  242. 4,3,1,0,
  243. 5,3,1,0,
  244. 0,0,2,0,
  245. 1,0,2,0,
  246. 2,0,2,0,
  247. 0,1,2,0,
  248. 1,1,2,0,
  249. 2,1,2,0,
  250. 3,1,2,0,
  251. 0,2,2,0,
  252. 1,2,2,0,
  253. 2,2,2,0,
  254. 3,2,2,0,
  255. 4,2,2,0,
  256. 1,3,2,0,
  257. 2,3,2,0,
  258. 3,3,2,0,
  259. 4,3,2,0,
  260. 5,3,2,0,
  261. 2,4,2,0,
  262. 3,4,2,0,
  263. 4,4,2,0,
  264. 5,4,2,0,
  265. 6,4,2,0,
  266. 0,1,3,0,
  267. 1,1,3,0,
  268. 2,1,3,0,
  269. 3,1,3,0,
  270. 0,2,3,0,
  271. 1,2,3,0,
  272. 2,2,3,0,
  273. 3,2,3,0,
  274. 4,2,3,0,
  275. 1,3,3,0,
  276. 2,3,3,0,
  277. 3,3,3,0,
  278. 4,3,3,0,
  279. 5,3,3,0,
  280. 2,4,3,0,
  281. 3,4,3,0,
  282. 4,4,3,0,
  283. 5,4,3,0,
  284. 6,4,3,0,
  285. 3,5,3,0,
  286. 4,5,3,0,
  287. 5,5,3,0,
  288. 6,5,3,0,
  289. 0,2,4,0,
  290. 1,2,4,0,
  291. 2,2,4,0,
  292. 3,2,4,0,
  293. 4,2,4,0,
  294. 1,3,4,0,
  295. 2,3,4,0,
  296. 3,3,4,0,
  297. 4,3,4,0,
  298. 5,3,4,0,
  299. 2,4,4,0,
  300. 3,4,4,0,
  301. 4,4,4,0,
  302. 5,4,4,0,
  303. 6,4,4,0,
  304. 3,5,4,0,
  305. 4,5,4,0,
  306. 5,5,4,0,
  307. 6,5,4,0,
  308. 4,6,4,0,
  309. 5,6,4,0,
  310. 6,6,4,0,
  311. 1,3,5,0,
  312. 2,3,5,0,
  313. 3,3,5,0,
  314. 4,3,5,0,
  315. 2,4,5,0,
  316. 3,4,5,0,
  317. 4,4,5,0,
  318. 5,4,5,0,
  319. 3,5,5,0,
  320. 4,5,5,0,
  321. 5,5,5,0,
  322. 6,5,5,0,
  323. 4,6,5,0,
  324. 5,6,5,0,
  325. 6,6,5,0,
  326. 2,4,6,0,
  327. 3,4,6,0,
  328. 4,4,6,0,
  329. 3,5,6,0,
  330. 4,5,6,0,
  331. 5,5,6,0,
  332. 4,6,6,0,
  333. 5,6,6,0,
  334. 6,6,6,0
  335. };
  336. // The encoding lookup table. There are 3^5 possible entries corresponding to
  337. // 5 emmiters: BP, RT, GT, BT, RN
  338. BYTE gajStorageTable[CT_STORAGE] = {
  339. 0, 1, 2, 3, 4, 5, 6, 7, 8,
  340. 13, 14, 15, 17, 18, 19, 21, 22, 23,
  341. 33, 34, 35, 38, 39, 40, 43, 44, 45,
  342. 12, 13, 14, 16, 17, 18, 20, 21, 22,
  343. 32, 33, 34, 37, 38, 39, 42, 43, 44,
  344. 56, 57, 58, 61, 62, 63, 66, 67, 68,
  345. 31, 32, 33, 36, 37, 38, 41, 42, 43,
  346. 55, 56, 57, 60, 61, 62, 65, 66, 67,
  347. 79, 80, 81, 84, 85, 86, 88, 89, 90,
  348. 9, 10, 11, 13, 14, 15, 17, 18, 19,
  349. 28, 29, 30, 33, 34, 35, 38, 39, 40,
  350. 52, 53, 54, 57, 58, 59, 62, 63, 64,
  351. 27, 28, 29, 32, 33, 34, 37, 38, 39,
  352. 51, 52, 53, 56, 57, 58, 61, 62, 63,
  353. 75, 76, 77, 80, 81, 82, 85, 86, 87,
  354. 50, 51, 52, 55, 56, 57, 60, 61, 62,
  355. 74, 75, 76, 79, 80, 81, 84, 85, 86,
  356. 95, 96, 97, 99,100,101,103,104,105,
  357. 24, 25, 26, 28, 29, 30, 33, 34, 35,
  358. 47, 48, 49, 52, 53, 54, 57, 58, 59,
  359. 71, 72, 73, 76, 77, 78, 81, 82, 83,
  360. 46, 47, 48, 51, 52, 53, 56, 57, 58,
  361. 70, 71, 72, 75, 76, 77, 80, 81, 82,
  362. 92, 93, 94, 96, 97, 98,100,101,102,
  363. 69, 70, 71, 74, 75, 76, 79, 80, 81,
  364. 91, 92, 93, 95, 96, 97, 99,100,101,
  365. 106,107,108,109,110,111,112,113,114
  366. };
  367. BYTE gajStorageTableBloated[CT_STORAGE] = {
  368. 0, 2, 5, 6, 8, 8, 22, 23, 23,
  369. 33, 35, 40, 43, 45, 45, 44, 45, 45,
  370. 61, 63, 63, 66, 68, 68, 67, 68, 68,
  371. 31, 33, 38, 41, 43, 43, 66, 67, 67,
  372. 79, 81, 86, 88, 90, 90, 89, 90, 90,
  373. 84, 86, 86, 88, 90, 90, 89, 90, 90,
  374. 74, 76, 81, 84, 86, 86, 85, 86, 86,
  375. 95, 97,101,103,105,105,104,105,105,
  376. 99,101,101,103,105,105,104,105,105,
  377. 24, 26, 30, 33, 35, 35, 58, 59, 59,
  378. 71, 73, 78, 81, 83, 83, 82, 83, 83,
  379. 96, 98, 98,100,102,102,101,102,102,
  380. 69, 71, 76, 79, 81, 81,100,101,101,
  381. 106,108,111,112,114,114,113,114,114,
  382. 109,111,111,112,114,114,113,114,114,
  383. 91, 93, 97, 99,101,101,100,101,101,
  384. 106,108,111,112,114,114,113,114,114,
  385. 109,111,111,112,114,114,113,114,114,
  386. 46, 48, 53, 56, 58, 58, 81, 82, 82,
  387. 92, 94, 98,100,102,102,101,102,102,
  388. 96, 98, 98,100,102,102,101,102,102,
  389. 69, 71, 76, 79, 81, 81,100,101,101,
  390. 106,108,111,112,114,114,113,114,114,
  391. 109,111,111,112,114,114,113,114,114,
  392. 91, 93, 97, 99,101,101,100,101,101,
  393. 106,108,111,112,114,114,113,114,114,
  394. 109,111,111,112,114,114,113,114,114
  395. };
  396. static const F_RGB * gaOutTable = gaOutTableRGB;
  397. /* illegal index in gajStorage1[] has been set to the closest legal index, NT bug #435222 */
  398. BYTE gajStorage1[7*7*7] =
  399. {
  400. 0x00,0x01,0x02,0x02,0x05,0x05,0x08,0x00,0x03,0x04,0x05,0x05,0x08,0x08,0x03,0x03,
  401. 0x06,0x07,0x08,0x08,0x17,0x10,0x06,0x06,0x07,0x08,0x17,0x17,0x10,0x14,0x14,0x15,
  402. 0x16,0x17,0x17,0x14,0x14,0x14,0x15,0x16,0x17,0x2d,0x29,0x29,0x29,0x2a,0x2b,0x2c,
  403. 0x2d,0x09,0x0a,0x0b,0x0b,0x0f,0x0f,0x13,0x0c,0x0d,0x0e,0x0f,0x0f,0x13,0x13,0x0c,
  404. 0x10,0x11,0x12,0x13,0x13,0x17,0x10,0x10,0x14,0x15,0x16,0x17,0x17,0x24,0x14,0x14,
  405. 0x15,0x16,0x17,0x2d,0x24,0x29,0x29,0x2a,0x2b,0x2c,0x2d,0x29,0x29,0x29,0x2a,0x2b,
  406. 0x2c,0x2d,0x18,0x19,0x1a,0x1a,0x1e,0x1e,0x23,0x1b,0x1c,0x1d,0x1e,0x1e,0x23,0x23,
  407. 0x1f,0x20,0x21,0x22,0x23,0x23,0x28,0x1f,0x24,0x25,0x26,0x27,0x28,0x28,0x24,0x24,
  408. 0x29,0x2a,0x2b,0x2c,0x2d,0x24,0x29,0x29,0x2a,0x2b,0x2c,0x2d,0x29,0x29,0x41,0x41,
  409. 0x42,0x43,0x44,0x18,0x19,0x1a,0x31,0x31,0x31,0x36,0x2e,0x2f,0x30,0x31,0x31,0x36,
  410. 0x36,0x32,0x33,0x34,0x35,0x36,0x36,0x3b,0x32,0x37,0x38,0x39,0x3a,0x3b,0x3b,0x37,
  411. 0x37,0x3c,0x3d,0x3e,0x3f,0x40,0x37,0x3c,0x3c,0x41,0x42,0x43,0x44,0x3c,0x3c,0x41,
  412. 0x41,0x42,0x43,0x44,0x2e,0x2f,0x30,0x31,0x31,0x49,0x49,0x2e,0x2f,0x30,0x31,0x49,
  413. 0x49,0x49,0x45,0x46,0x47,0x48,0x49,0x49,0x4e,0x45,0x4a,0x4b,0x4c,0x4d,0x4e,0x4e,
  414. 0x4a,0x4a,0x4f,0x50,0x51,0x52,0x53,0x4a,0x4f,0x4f,0x54,0x55,0x56,0x57,0x4f,0x4f,
  415. 0x54,0x54,0x58,0x59,0x5a,0x2e,0x2f,0x30,0x31,0x49,0x49,0x49,0x45,0x46,0x47,0x48,
  416. 0x49,0x49,0x49,0x45,0x46,0x47,0x48,0x49,0x49,0x4e,0x5b,0x5b,0x5c,0x5d,0x5e,0x4e,
  417. 0x4e,0x5b,0x5b,0x5f,0x60,0x61,0x62,0x53,0x5b,0x5f,0x5f,0x63,0x64,0x65,0x66,0x5f,
  418. 0x5f,0x63,0x63,0x67,0x68,0x69,0x45,0x46,0x47,0x48,0x49,0x49,0x49,0x45,0x46,0x47,
  419. 0x48,0x49,0x49,0x49,0x5b,0x5b,0x5c,0x5d,0x5e,0x5e,0x4e,0x5b,0x5b,0x5c,0x5d,0x5e,
  420. 0x5e,0x62,0x5b,0x6a,0x6a,0x6b,0x6c,0x62,0x62,0x6a,0x6a,0x6a,0x6d,0x6e,0x6f,0x66,
  421. 0x6a,0x6a,0x6d,0x6d,0x70,0x71,0x72};
  422. // gamma tables
  423. ULONG gulGamma = DEFAULT_CT_CONTRAST;
  424. // all the info needed to perform blends of fore and background pixels
  425. typedef struct _BLENDINFO
  426. {
  427. int iRedL; int iRedR; // shift numbers
  428. int iGreL; int iGreR; // shift numbers
  429. int iBluL; int iBluR; // shift numbers
  430. ULONG flRed; // mask bits
  431. ULONG flGre; // mask bits
  432. ULONG flBlu; // mask bits
  433. LONG lRedF; // foreground components
  434. LONG lGreF;
  435. LONG lBluF;
  436. PBYTE pjGamma; // pointers to gamma tables
  437. PBYTE pjGammaInv;
  438. } BLENDINFO;
  439. /********************************************************************
  440. * *
  441. * 16.16 fix point numbers representing *
  442. * *
  443. * aulB[16] = floor(65536 * (a[k]/16)^(1/gamma) + 1/2) *
  444. * aulIB[k] = floor(65536 * (1 - a[k]/16)^(1/gamma) + 1/2) *
  445. * *
  446. * where a[k] = k == 0 ? 0 : k+1 *
  447. * gamma = 2.33 *
  448. ********************************************************************/
  449. static const ULONG aulB[16] =
  450. {
  451. 0 , 26846 , 31949 , 36148 , 39781 , 43019 , 45961 , 48672 ,
  452. 51196 , 53564 , 55800 , 57923 , 59948 , 61885 , 63745 , 65536
  453. };
  454. static const ULONG aulIB[16] =
  455. { 0 , 3650 , 5587 , 7612 , 9735 , 11971 , 14339 , 16863 ,
  456. 19574 , 22516 , 25754 , 29387 , 33586 , 38689 , 45597 , 65536
  457. };
  458. /******************************Public*Routine******************************\
  459. * *
  460. * Routine Name: *
  461. * *
  462. * pvFillOpaqTable *
  463. * *
  464. * Routine Description: *
  465. * *
  466. * The case of opaqe text is special because the destiantion pixels *
  467. * must be chosen from a set of 16 colors. This routine calculates *
  468. * those 16 colors and puts them in an array. This array is addressed *
  469. * by the value of the 4-bpp antialiased glyph. *
  470. * *
  471. * Let k be the value contained in a 4-bpp antialiased glyph value. *
  472. * Thus the allowed range for k is *
  473. * *
  474. * k = 0,1..15 *
  475. * *
  476. * This is interpreted as a blending fraction alpha_k given by *
  477. * *
  478. * alpha_k = a_k / 16 *
  479. * where *
  480. * *
  481. * a_k = (0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) *
  482. * *
  483. * The color values are normalized by the maximum color value *
  484. * that a color channel can have, i_max *
  485. * *
  486. * For a single color channel, the normalized foreground and *
  487. * background colors are given by *
  488. * *
  489. * c0 = i0 / i_max , *
  490. * *
  491. * c1 = i1 / i_max . *
  492. * *
  493. * The blended and gamma corrected color value is *
  494. * *
  495. * c_k = (1 - alpha_k) * c0^gam + alpha_k * c1^gam)^(1/gam) *
  496. * *
  497. * The unnormalized blended and gamma corrected color values *
  498. * are: *
  499. * *
  500. * i_k = floor( i_max * c_k + 1/2) *
  501. * *
  502. * wbere 'gam' is the gamma correction value which I have chosen *
  503. * to be equal to 2.33. *
  504. * *
  505. * In order to speed up the caluclation we cut corners by *
  506. * making some approximations. The basic idea is to replace *
  507. * the slow process of calculating various powers of real *
  508. * numbers by table look up's. *
  509. * *
  510. * The first table G[i] is defined as follows: *
  511. * *
  512. * G[i] = floor(g_max * (i/i_max)^gam + 1/2) , *
  513. * *
  514. * where *
  515. * *
  516. * 0 <= i <= i_max , *
  517. * and *
  518. * 0 <= G[i] <= g_max . *
  519. * *
  520. * The second table is essentially the inverse to G[i], which *
  521. * I shall call I[j]. *
  522. * *
  523. * I[j] = floor(i_max * (j / j_max)^(1/gam) + 1/2) , *
  524. * *
  525. * 0 <= j <= j_max . *
  526. * *
  527. * i_max = 31 (255) *
  528. * g_max = 65536 *
  529. * j_max = 256 *
  530. * *
  531. * The complete process of calculating the blended and gamma *
  532. * corrected color is given by *
  533. * *
  534. * g = 16*G[i0]; *
  535. * dg = G[i1] - G[i0]; *
  536. * c = 16 * g_max / j_max; // 2^12 *
  537. * for (k = 0; k < 16; k++) { *
  538. * i[k] = I[ (g + c/2)/c]; *
  539. * g += dg; *
  540. * } *
  541. * *
  542. * Arguments: *
  543. * *
  544. * cj ............................... size of each array element in *
  545. * BYTE's. *
  546. * *
  547. * uF ............................... a 32-bit value whose lowest *
  548. * 16 bits contain the foreground *
  549. * color *
  550. * *
  551. * uB ............................... a 32-bit value whose lowest 16 *
  552. * bits contain the background *
  553. * color *
  554. * *
  555. * pS ............................... pointer to destination surface *
  556. * *
  557. * Return Value: *
  558. * *
  559. * pointer to color table *
  560. * *
  561. \**************************************************************************/
  562. VOID *pvFillOpaqTable(ULONG size, ULONG uF, ULONG uB, SURFACE *pS)
  563. {
  564. int iRedL, iRedR; // shift numbers
  565. int iGreL, iGreR; // shift numbers
  566. int iBluL, iBluR; // shift numbers
  567. ULONG uRed, dRed, flRed;
  568. ULONG uGre, dGre, flGre;
  569. ULONG uBlu, dBlu, flBlu;
  570. ULONG ul;
  571. static ULONG aulCache[16]; // set to zero prior to first call
  572. static HANDLE hCache; // set to zero prior to first call
  573. static ULONG uFCache;
  574. static ULONG uBCache;
  575. static ULONG sizeCache;
  576. static VOID *pv = (VOID*) aulCache;
  577. // I have been assured of two things....
  578. // 1) Since this routine is a child of EngTextOut then there
  579. // will be only one thread in this routine at any one time.
  580. // This means that I do not need to protect the color
  581. // table, aulCache[] with a critical section
  582. // 2) I have been assured that the format of a surface
  583. // is unique. Thus if the handle of the surface matches
  584. // the handle of the cached color table, then the
  585. // formats of the surface are the same.
  586. if (pS->hGet() == hCache && uB == uBCache && uF == uFCache)
  587. {
  588. ASSERTGDI(size == sizeCache, "size != sizeCache");
  589. }
  590. else
  591. {
  592. sizeCache = size;
  593. uFCache = uF;
  594. uBCache = uB;
  595. hCache = pS->hGet();
  596. #if NEVER
  597. if (size == sizeof(USHORT))
  598. {
  599. ASSERTGDI(uF <= USHRT_MAX, "bad uF");
  600. ASSERTGDI(uB <= USHRT_MAX, "bad uB");
  601. }
  602. else if (size == sizeof(ULONG))
  603. {
  604. ASSERTGDI(uF < 0x1000000, "bad uF");
  605. ASSERTGDI(uB < 0x1000000, "bad uB");
  606. }
  607. else
  608. {
  609. RIP("bad size");
  610. }
  611. #endif
  612. XEPALOBJ xpo;
  613. if(pS->pPal == NULL)
  614. {
  615. PDEVOBJ pdo(pS->hdev());
  616. xpo.ppalSet(pdo.ppalSurf());
  617. }
  618. else
  619. {
  620. xpo.ppalSet(pS->pPal);
  621. }
  622. ASSERTGDI(xpo.bValid(), "Invalid XEPALOBJ" );
  623. if (xpo.bIsBitfields())
  624. {
  625. flRed = xpo.flRed();
  626. flGre = xpo.flGre();
  627. flBlu = xpo.flBlu();
  628. iRedR = (int) (xpo.cRedRight() + xpo.cRedMiddle() - 8);
  629. iGreR = (int) (xpo.cGreRight() + xpo.cGreMiddle() - 8);
  630. iBluR = (int) (xpo.cBluRight() + xpo.cBluMiddle() - 8);
  631. }
  632. else
  633. {
  634. int cBits;
  635. ULONG flBits;
  636. if (size == sizeof(USHORT))
  637. {
  638. // assumes standard RGB is 5+5+5 for 16-bit color
  639. cBits = 5;
  640. flBits = 0x1f;
  641. }
  642. else
  643. {
  644. cBits = 8;
  645. flBits = 0xff;
  646. }
  647. if (xpo.bIsRGB())
  648. {
  649. flRed = flBits;
  650. flGre = flRed << cBits;
  651. flBlu = flGre << cBits;
  652. iRedR = cBits - 8;
  653. iGreR = iRedR + cBits;
  654. iBluR = iGreR + cBits;
  655. }
  656. else if (xpo.bIsBGR())
  657. {
  658. flBlu = flBits;
  659. flGre = flBlu << cBits;
  660. flRed = flGre << cBits;
  661. iBluR = cBits - 8;
  662. iGreR = iBluR + cBits;
  663. iRedR = iGreR + cBits;
  664. }
  665. else
  666. {
  667. RIP("Palette format not supported\n");
  668. }
  669. }
  670. #define GAMMA (ULONG) RFONTOBJ::gTables[0]
  671. /***************************************************************
  672. * *
  673. * Now I shall calculate the shift numbers. *
  674. * *
  675. * I shall explain the shift numbers for the red channel. *
  676. * The green and blue channels are treated in the same way. *
  677. * *
  678. * I want to shift the red bits of the red channel colors *
  679. * so that the most significant bit of the red channel *
  680. * bits corresponds to a value of 2^7. This means that *
  681. * if I mask off all of the other color bits, then I *
  682. * will end up with a number between zero and 255. This *
  683. * process of going to the 0 .. 255 range looks like *
  684. * *
  685. * ((color & flRed) << iRedL) >> iRedR *
  686. * *
  687. * Only one of iRedL or iRedR is non zero. *
  688. * *
  689. * I then use this number to index into a 256 element *
  690. * gamma correction table. The gamma correction table *
  691. * elements are BYTE values that are in the range 0 .. 255. *
  692. * *
  693. ***************************************************************/
  694. iRedL = 0;
  695. if (iRedR < 0)
  696. {
  697. iRedL = - iRedR;
  698. iRedR = 0;
  699. }
  700. uRed = GAMMA[(((uB & flRed) << iRedL) >> iRedR) & 255];
  701. dRed = GAMMA[(((uF & flRed) << iRedL) >> iRedR) & 255];
  702. dRed -= uRed;
  703. uRed *= 16;
  704. iGreL = 0;
  705. if (iGreR < 0)
  706. {
  707. iGreL = - iGreR;
  708. iGreR = 0;
  709. }
  710. uGre = GAMMA[(((uB & flGre) << iGreL) >> iGreR) & 255];
  711. dGre = GAMMA[(((uF & flGre) << iGreL) >> iGreR) & 255];
  712. dGre -= uGre;
  713. uGre *= 16;
  714. iBluL = 0;
  715. if (iBluR < 0)
  716. {
  717. iBluL = - iBluR;
  718. iBluR = 0;
  719. }
  720. uBlu = GAMMA[(((uB & flBlu) << iBluL) >> iBluR) & 255];
  721. dBlu = GAMMA[(((uF & flBlu) << iBluL) >> iBluR) & 255];
  722. dBlu -= uBlu;
  723. uBlu *= 16;
  724. #undef GAMMA
  725. #if DBG
  726. if (gflFontDebug & DEBUG_AA)
  727. {
  728. DbgPrint(
  729. "flRed = %-#x\n"
  730. "iRedL = %d\n"
  731. "iRedR = %d\n"
  732. "uRed = %-#x\n"
  733. "dRed = %-#x\n"
  734. , flRed, iRedL, iRedR, uRed, dRed
  735. );
  736. DbgPrint(
  737. "flGre = %-#x\n"
  738. "iGreL = %d\n"
  739. "iGreR = %d\n"
  740. "uGre = %-#x\n"
  741. "dGre = %-#x\n"
  742. , flGre, iGreL, iGreR, uGre, dGre
  743. );
  744. DbgPrint(
  745. "flBlu = %-#x\n"
  746. "iBluL = %d\n"
  747. "iBluR = %d\n"
  748. "uBlu = %-#x\n"
  749. "dBlu = %-#x\n"
  750. , flBlu, iBluL, iBluR, uBlu, dBlu
  751. );
  752. }
  753. #endif
  754. #define IGAMMA (ULONG) RFONTOBJ::gTables[1]
  755. uRed += dRed;
  756. uGre += dGre;
  757. uBlu += dBlu;
  758. if (size == sizeof(USHORT))
  759. {
  760. USHORT *aus = (USHORT*) pv;
  761. USHORT *pus = aus;
  762. *pus++ = (USHORT) uB;
  763. #if DBG
  764. if (gflFontDebug & DEBUG_AA)
  765. {
  766. DbgPrint(
  767. "Table of 16-bit colors ...\n"
  768. "------------------------------------\n"
  769. " %0-#4x %0-#4x %0-#4x = %0-#6x\n"
  770. , (uB & flRed) >> xpo.cRedRight()
  771. , (uB & flGre) >> xpo.cGreRight()
  772. , (uB & flBlu) >> xpo.cBluRight()
  773. , uB
  774. );
  775. }
  776. #endif
  777. while (pus < aus + 15)
  778. {
  779. ul = (((IGAMMA[(uRed += dRed)/16 & 255] << iRedR) >> iRedL) & flRed);
  780. ul |= (((IGAMMA[(uGre += dGre)/16 & 255] << iGreR) >> iGreL) & flGre);
  781. ul |= (((IGAMMA[(uBlu += dBlu)/16 & 255] << iBluR) >> iBluL) & flBlu);
  782. *pus++ = (USHORT) ul;
  783. #if DBG
  784. if (gflFontDebug & DEBUG_AA)
  785. {
  786. DbgPrint(
  787. " %0-#4x %0-#4x %0-#4x = %0-#6x\n"
  788. , IGAMMA[uRed/16 & 255]
  789. , IGAMMA[uGre/16 & 255]
  790. , IGAMMA[uBlu/16 & 255]
  791. , ul
  792. );
  793. }
  794. #endif
  795. }
  796. *pus = (USHORT) uF;
  797. #if DBG
  798. if (gflFontDebug & DEBUG_AA)
  799. {
  800. DbgPrint(
  801. " %0-#4x %0-#4x %0-#4x = %0-#6x\n"
  802. , (uF & flRed) >> xpo.cRedRight()
  803. , (uF & flGre) >> xpo.cGreRight()
  804. , (uF & flBlu) >> xpo.cBluRight()
  805. , uF
  806. );
  807. }
  808. #endif
  809. }
  810. else
  811. {
  812. ASSERTGDI(size == sizeof(ULONG), "bad size");
  813. ULONG *aul = (ULONG*) pv;
  814. ULONG *pul = aul;
  815. *pul++ = uB;
  816. #if DBG
  817. if (gflFontDebug & DEBUG_AA)
  818. {
  819. DbgPrint(
  820. "Table of 32-bit colors .....\n"
  821. "------------------------------------\n"
  822. " %0-#4x %0-#4x %0-#4x = %0-#8x\n"
  823. , (uB & flRed) >> xpo.cRedRight()
  824. , (uB & flGre) >> xpo.cGreRight()
  825. , (uB & flBlu) >> xpo.cBluRight()
  826. , uB
  827. );
  828. }
  829. #endif
  830. while (pul < aul + 15)
  831. {
  832. ul = (((IGAMMA[(uRed += dRed)/16 & 255] << iRedR) >> iRedL) & flRed);
  833. ul |= (((IGAMMA[(uGre += dGre)/16 & 255] << iGreR) >> iGreL) & flGre);
  834. ul |= (((IGAMMA[(uBlu += dBlu)/16 & 255] << iBluR) >> iBluL) & flBlu);
  835. *pul++ = ul;
  836. #if DBG
  837. if (gflFontDebug & DEBUG_AA)
  838. {
  839. DbgPrint(
  840. "%0-#4x %0-#4x %0-#4x = %0-#8x\n"
  841. , IGAMMA[uRed/16 & 255]
  842. , IGAMMA[uGre/16 & 255]
  843. , IGAMMA[uBlu/16 & 255]
  844. , ul
  845. );
  846. }
  847. #endif
  848. }
  849. *pul = uF;
  850. #if DBG
  851. if (gflFontDebug & DEBUG_AA)
  852. {
  853. DbgPrint(
  854. " %0-#4x %0-#4x %0-#4x = %0-#8x\n"
  855. , (uF & flRed) >> xpo.cRedRight()
  856. , (uF & flGre) >> xpo.cGreRight()
  857. , (uF & flBlu) >> xpo.cBluRight()
  858. , uF
  859. );
  860. }
  861. #endif
  862. }
  863. #undef IGAMMA
  864. }
  865. return(pv);
  866. }
  867. // Indices into the default palette
  868. #define I_BLACK 0
  869. #define I_DKGRAY 248
  870. #define I_GRAY 7
  871. #define I_WHITE 255
  872. static const BYTE ajWhiteOnBlack[16] = {
  873. I_BLACK , I_BLACK , I_DKGRAY , I_DKGRAY
  874. , I_DKGRAY , I_GRAY , I_GRAY , I_GRAY
  875. , I_GRAY , I_GRAY , I_GRAY , I_WHITE
  876. , I_WHITE , I_WHITE , I_WHITE , I_WHITE
  877. };
  878. static const BYTE ajBlackOnWhite[16] = {
  879. I_WHITE , I_WHITE , I_WHITE , I_WHITE
  880. , I_GRAY , I_GRAY , I_GRAY , I_GRAY
  881. , I_GRAY , I_DKGRAY , I_DKGRAY , I_DKGRAY
  882. , I_DKGRAY , I_DKGRAY , I_BLACK , I_BLACK
  883. };
  884. static const BYTE ajBlackOnBlack[16] = {
  885. I_BLACK, I_BLACK, I_BLACK, I_BLACK,
  886. I_BLACK, I_BLACK, I_BLACK, I_BLACK,
  887. I_BLACK, I_BLACK, I_BLACK, I_BLACK,
  888. I_BLACK, I_BLACK, I_BLACK, I_BLACK
  889. };
  890. static const BYTE ajWhiteOnWhite[16] = {
  891. I_WHITE, I_WHITE, I_WHITE, I_WHITE,
  892. I_WHITE, I_WHITE, I_WHITE, I_WHITE,
  893. I_WHITE, I_WHITE, I_WHITE, I_WHITE,
  894. I_WHITE, I_WHITE, I_WHITE, I_WHITE
  895. };
  896. #if 0
  897. /******************************Public*Routine******************************\
  898. * *
  899. * Routine Name *
  900. * *
  901. * vSrcOpaqCopyS4D8 *
  902. * *
  903. * Routine Description: *
  904. * *
  905. * Copies a 4bpp gray bitmap onto an 8bpp palettized surface. The *
  906. * only case that this routine handles is white text on a black *
  907. * background or black text on a white background. *
  908. * *
  909. * Arguments: *
  910. * *
  911. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  912. * This points to a 4-bit per pixel anti-aliased bitmap *
  913. * whose scans start and end on 32-bit boundaries. *
  914. * SrcLeft - left (starting) pixel in src rectangle *
  915. * That is, this is the number of pixels in from the edge *
  916. * of the start of each scan line that the actual pixels *
  917. * of the image begins. All pixels before and after the *
  918. * image pixels of the scan are to be ignored. This offset *
  919. * has been put in to guarantee that 32-bit boundaries *
  920. * in the 4bpp source correspond to 32-bit boundaries *
  921. * in the destination. *
  922. * DeltaSrcIn - bytes from one src scan line to next *
  923. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  924. * DstLeft - left(first) dst pixel *
  925. * DstRight - exclusive right dst pixel *
  926. * DeltaDstIn - bytes from one Dst scan line to next *
  927. * cy - number of scan lines *
  928. * uF - Foreground color *
  929. * uB - Background color *
  930. * pS - pointer to destination SURFACE *
  931. * *
  932. * If the destination suface is 8-bits per pixels then the only form *
  933. * of antialiased text allowed is opaque textout with foreground and *
  934. * background are either black or white. *
  935. * *
  936. * On palette devices (8-bit devices) we are guaranteed to have 4 shades *
  937. * of gray to work with. These gray come from 4 of the 20 reserved *
  938. * entries in the palette and are given by: *
  939. * *
  940. * name rgb index *
  941. * *
  942. * BLACK (0x00, 0x00, 0x00) 0 *
  943. * DKGRAY (0x80, 0x80, 0x80) 12 *
  944. * GRAY (0xc0, 0xc0, 0xc0) 7 *
  945. * WHITE (0xff, 0xff, 0xff) 19 *
  946. * *
  947. * There are, two cases of interest: 1) white text on black; and 2) *
  948. * black text on white. The various levels of gray seen on the screen *
  949. * is controled by the 16 values of blending as defined by each of the *
  950. * 4-bit gray levels in the glyphs images. The allowed value of blending *
  951. * are: *
  952. * *
  953. * alpha[i] = (i == 0) ? 0 : (i+1)/16 *
  954. * *
  955. * where i = <value of 4-bit pixel> *
  956. * *
  957. * For case 1) (white text on a black background) the gamma corrected *
  958. * color channel values are given by: *
  959. * *
  960. * c[i] = floor(255*(alpha[i]^(1/gamma)) + 1/2) *
  961. * *
  962. * which is equivalent to the following table *
  963. * *
  964. * c[16] = { 0, 104, 124, 141, *
  965. * 155, 167, 179, 189, *
  966. * 199, 208, 217, 225, *
  967. * 233, 241, 248, 255 }; *
  968. * *
  969. * This result applies to each of the three color channels. *
  970. * *
  971. * The problem is that there are only four colors available: BLACK, DKGRAY, *
  972. * GRAY, WHITE with the color values of 0, 128, 192, and 255 respectively. *
  973. * This means that the color table that is used is an *
  974. * approximation to the correct color table given by: *
  975. * *
  976. * c' = { BLACK, BLACK, *
  977. * DKGRAY, DKGRAY, DKGRAY, *
  978. * GRAY, GRAY, GRAY, GRAY, GRAY, GRAY, *
  979. * WHITE, WHITE, WHITE, WHITE, WHITE }; *
  980. * *
  981. * For case 2) (black text on white) the gamma corrected color channel *
  982. * values are given by: *
  983. * *
  984. * d[i] = floor(255*((1-alpha[i])^(1/gamma) + 1/2) = c[15 - i] *
  985. * = *
  986. * { *
  987. * 255, 248, 241, 233, *
  988. * 225, 217, 208, 199, *
  989. * 189, 179, 167, 155, *
  990. * 141, 124, 104, 0 *
  991. * }; *
  992. * *
  993. * which is approximated by *
  994. * *
  995. * d' = { *
  996. * WHITE, WHITE, WHITE, WHITE, *
  997. * GRAY, GRAY, GRAY, GRAY, GRAY, *
  998. * DKGRAY, DKGRAY, DKGRAY, DKGRAY, DKGRAY, *
  999. * BLACK, BLACK *
  1000. * } *
  1001. * *
  1002. * *
  1003. * Return Value: *
  1004. * *
  1005. * None *
  1006. * *
  1007. \**************************************************************************/
  1008. VOID
  1009. vSrcOpaqCopyS4D8(
  1010. PBYTE pjSrcIn,
  1011. LONG SrcLeft,
  1012. LONG DeltaSrcIn,
  1013. PBYTE pjDstIn,
  1014. LONG DstLeft,
  1015. LONG DstRight,
  1016. LONG DeltaDstIn,
  1017. LONG cy,
  1018. ULONG uF,
  1019. ULONG uB,
  1020. SURFACE *pS
  1021. )
  1022. {
  1023. int cPreamble, cMiddle, cPostamble, A, B;
  1024. const BYTE *ajIndex;
  1025. BYTE jSrc, *pjSrc, *pjDst;
  1026. static const BYTE *apjIndex[4] = {
  1027. ajBlackOnBlack // uB = 0 uF = 0
  1028. , ajBlackOnWhite // uB = 0xff uF = 0
  1029. , ajWhiteOnBlack // uB = 0 uF = 0xff
  1030. , ajWhiteOnWhite // uB = 0xff uF = 0xff
  1031. };
  1032. #if DBG
  1033. if (gflFontDebug & DEBUG_AA)
  1034. {
  1035. DbgPrint(
  1036. "vSrcOpaqCopyS4D8(\n"
  1037. " PBYTE pjSrcIn = %-#x\n"
  1038. " LONG SrcLeft = %d\n"
  1039. " LONG DeltaSrcIn = %d\n"
  1040. " PBYTE pjDstIn = %-#x\n"
  1041. " LONG DstLeft = %d\n"
  1042. " LONG DstRight = %d\n"
  1043. " LONG DeltaDstIn = %d\n"
  1044. " LONG cy = %d\n"
  1045. " ULONG uF = %-#x\n"
  1046. " ULONG uB = %-#x\n"
  1047. " SURFACE *pS = %-#x\n"
  1048. ");\n\n"
  1049. , pjSrcIn
  1050. , SrcLeft
  1051. , DeltaSrcIn
  1052. , pjDstIn
  1053. , DstLeft
  1054. , DstRight
  1055. , DeltaDstIn
  1056. , cy
  1057. , uF
  1058. , uB
  1059. , pS
  1060. );
  1061. DbgBreakPoint();
  1062. }
  1063. #endif
  1064. ASSERTGDI((uF == 0xff) || (uF == 0), "Bad Foreground Color\n");
  1065. ASSERTGDI((uB == 0xff) || (uB == 0), "Bad Background Color\n");
  1066. ASSERTGDI((unsigned) pjSrcIn % 4 == 0,
  1067. "Source buffer not 32-bit aligned\n");
  1068. ASSERTGDI((unsigned) DeltaSrcIn % 4 == 0,
  1069. "Source scans are not 32-bit aligned\n");
  1070. /******************************************************************
  1071. * Select the appropriate byte table *
  1072. * *
  1073. * I take advantage of the restricted values of the foreground and *
  1074. * background colors to form an index into a table. This requires *
  1075. * that the foreground and bacground colors be either 0 or -1. *
  1076. ******************************************************************/
  1077. ajIndex = apjIndex[(uB & 1) + (uF & 2)];
  1078. /******************************************************************
  1079. * Each nyble of the source maps to a byte in the *
  1080. * destination. I want to separate the pixels into three *
  1081. * groups: preamble, middle, and postamble. The middle *
  1082. * pixels of the destination start and end on 32-bit *
  1083. * boundaries. The preamble and postamble are the *
  1084. * other pixels on the left and right respectively. *
  1085. * The preamble ends on a 32-bit address and the postamble *
  1086. * begins on a 32-bit address. *
  1087. * *
  1088. * It is possible for small images (1 or 2 wide) to be *
  1089. * contained completely within a DWORD of the destination such *
  1090. * that the destination image does not start on, contain, or *
  1091. * end on a 32-bit boundary. I treat this situation as *
  1092. * special cases. *
  1093. ******************************************************************/
  1094. pjSrcIn += SrcLeft / 2; // 2 pixels per source byte
  1095. pjDstIn += DstLeft; // one byte per dest pixel
  1096. A = (DstLeft + 3) & ~3; // A = 4 * ceil(DstLeft/4)
  1097. B = (DstRight ) & ~3; // B = 4 * floor(DstRight/4)
  1098. if (B < A)
  1099. {
  1100. /*****************************************************
  1101. * There are only three ways that you can get here *
  1102. * *
  1103. * 1) DstLeft & 3 == 1 && DstRight == DstLeft + 1 *
  1104. * 2) DstLeft & 3 == 1 && DstRight == DstLeft + 2 *
  1105. * 3) DstLeft & 3 == 2 && DstRight == DstLeft + 1 *
  1106. *****************************************************/
  1107. if ((DstLeft & 3) == 1)
  1108. {
  1109. *pjDstIn++ = ajIndex[*pjSrcIn++ & 15];
  1110. }
  1111. if ((DstRight & 3) == 3)
  1112. {
  1113. *pjDstIn = ajIndex[*pjSrcIn >> 4];
  1114. }
  1115. }
  1116. else
  1117. {
  1118. cPreamble = A - DstLeft; // # pixels in preamble
  1119. cMiddle = (B - A)/4;
  1120. cPostamble = DstRight - B; // # pixels in postamble
  1121. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  1122. {
  1123. int cLast;
  1124. int i;
  1125. pjSrc = pjSrcIn;
  1126. pjDst = pjDstIn;
  1127. switch (cPreamble)
  1128. {
  1129. case 3:
  1130. jSrc = *pjSrc++;
  1131. *pjDst++ = ajIndex[jSrc & 15];
  1132. // fall through
  1133. case 2:
  1134. jSrc = *pjSrc;
  1135. *pjDst++ = ajIndex[jSrc >> 4];
  1136. // fall through
  1137. case 1:
  1138. jSrc = *pjSrc++;
  1139. *pjDst++ = ajIndex[jSrc & 15];
  1140. // fall through
  1141. }
  1142. for (i = 0 ; i < cMiddle ; i++)
  1143. {
  1144. jSrc = *pjSrc++;
  1145. *pjDst++ = ajIndex[jSrc >> 4];
  1146. *pjDst++ = ajIndex[jSrc & 15];
  1147. jSrc = *pjSrc++;
  1148. *pjDst++ = ajIndex[jSrc >> 4];
  1149. *pjDst++ = ajIndex[jSrc & 15];
  1150. }
  1151. if (cLast = cPostamble)
  1152. {
  1153. cLast -= 1;
  1154. jSrc = *pjSrc++;
  1155. *pjDst++ = ajIndex[jSrc >> 4];
  1156. if (cLast)
  1157. {
  1158. cLast -= 1;
  1159. *pjDst++ = ajIndex[jSrc & 15];
  1160. if (cLast)
  1161. {
  1162. jSrc = *pjSrc;
  1163. *pjDst++ = ajIndex[jSrc >> 4];
  1164. *pjDst++ = ajIndex[jSrc & 15];
  1165. }
  1166. }
  1167. }
  1168. }
  1169. }
  1170. }
  1171. /******************************Public*Routine******************************\
  1172. * *
  1173. * Routine Name *
  1174. * *
  1175. * vSrcTranCopyS4D8 *
  1176. * *
  1177. * Routine Description: *
  1178. * *
  1179. * Despite what the title implies this routine is not a `transparent' *
  1180. * copy of a 4bpp gray scale bitmap onto an arbitrary 8bpp surface. *
  1181. * What it really does is do an opaque copy of a 4bpp gray scale *
  1182. * bitmap onto an 8bpp surface EXCEPT for the case where the value *
  1183. * of the 4bpp gray scale pixel is zero. In that special case, the *
  1184. * destination pixel is untouched. This routine nearly identical to *
  1185. * the routine named `vSrcOpaqCopyS4D8' except that this routine tests *
  1186. * each 4bpp pixel to see if it is zero. *
  1187. * *
  1188. * Arguments: *
  1189. * *
  1190. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  1191. * This points to a 4-bit per pixel anti-aliased bitmap *
  1192. * whose scans start and end on 32-bit boundaries. *
  1193. * SrcLeft - left (starting) pixel in src rectangle *
  1194. * That is, this is the number of pixels in from the edge *
  1195. * of the start of each scan line that the actual pixels *
  1196. * of the image begins. All pixels before and after the *
  1197. * image pixels of the scan are to be ignored. This offset *
  1198. * has been put in to guarantee that 32-bit boundaries *
  1199. * in the 4bpp source correspond to 32-bit boundaries *
  1200. * in the destination. *
  1201. * DeltaSrcIn - bytes from one src scan line to next *
  1202. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  1203. * DstLeft - left(first) dst pixel *
  1204. * DstRight - exclusive right dst pixel *
  1205. * DeltaDstIn - bytes from one Dst scan line to next *
  1206. * cy - number of scan lines *
  1207. * uF - Foreground color (0x00 or 0xff) *
  1208. * uB - Background color (not used) *
  1209. * pS - pointer to destination SURFACE *
  1210. * *
  1211. * Return Value: *
  1212. * *
  1213. * None *
  1214. * *
  1215. \**************************************************************************/
  1216. VOID
  1217. vSrcTranCopyS4D8(
  1218. PBYTE pjSrcIn,
  1219. LONG SrcLeft,
  1220. LONG DeltaSrcIn,
  1221. PBYTE pjDstIn,
  1222. LONG DstLeft,
  1223. LONG DstRight,
  1224. LONG DeltaDstIn,
  1225. LONG cy,
  1226. ULONG uF,
  1227. ULONG uB,
  1228. SURFACE *pS
  1229. )
  1230. {
  1231. int cPreamble, cMiddle, cPostamble, A, B;
  1232. const BYTE *ajIndex;
  1233. BYTE jSrc, *pjSrc, *pjDst;
  1234. static const BYTE *apjIndex[2] = {
  1235. ajBlackOnWhite // uF = 0 // black text
  1236. , ajWhiteOnBlack // uF = 0xFF // white text
  1237. };
  1238. #if DBG
  1239. if (gflFontDebug & DEBUG_AA)
  1240. {
  1241. DbgPrint(
  1242. "vSrcTranCopyS4D8(\n"
  1243. " PBYTE pjSrcIn = %-#x\n"
  1244. " LONG SrcLeft = %d\n"
  1245. " LONG DeltaSrcIn = %d\n"
  1246. " PBYTE pjDstIn = %-#x\n"
  1247. " LONG DstLeft = %d\n"
  1248. " LONG DstRight = %d\n"
  1249. " LONG DeltaDstIn = %d\n"
  1250. " LONG cy = %d\n"
  1251. " ULONG uF = %-#x\n"
  1252. " ULONG uB = %-#x\n"
  1253. " SURFACE *pS = %-#x\n"
  1254. ");\n\n"
  1255. , pjSrcIn
  1256. , SrcLeft
  1257. , DeltaSrcIn
  1258. , pjDstIn
  1259. , DstLeft
  1260. , DstRight
  1261. , DeltaDstIn
  1262. , cy
  1263. , uF
  1264. , uB
  1265. , pS
  1266. );
  1267. DbgBreakPoint();
  1268. }
  1269. #endif
  1270. ASSERTGDI((uF == 0xff) || (uF == 0), "Bad Foreground Color\n");
  1271. ASSERTGDI((unsigned) pjSrcIn % 4 == 0,
  1272. "Source buffer not 32-bit aligned\n");
  1273. ASSERTGDI((unsigned) DeltaSrcIn % 4 == 0,
  1274. "Source scans are not 32-bit aligned\n");
  1275. static const BYTE ajTranWhiteOnBlack[16] = {
  1276. I_BLACK , I_BLACK , I_DKGRAY , I_DKGRAY
  1277. , I_DKGRAY , I_GRAY , I_GRAY , I_GRAY
  1278. , I_GRAY , I_GRAY , I_GRAY , I_WHITE
  1279. , I_WHITE , I_WHITE , I_WHITE , I_WHITE
  1280. };
  1281. static const BYTE ajBlackOnWhite[16] = {
  1282. I_WHITE , I_WHITE , I_WHITE , I_WHITE
  1283. , I_GRAY , I_GRAY , I_GRAY , I_GRAY
  1284. , I_GRAY , I_DKGRAY , I_DKGRAY , I_DKGRAY
  1285. , I_DKGRAY , I_DKGRAY , I_BLACK , I_BLACK
  1286. };
  1287. ajIndex = apjIndex[uF & 1];
  1288. pjSrcIn += SrcLeft / 2; // 2 pixels per source byte
  1289. pjDstIn += DstLeft; // one byte per dest pixel
  1290. A = (DstLeft + 3) & ~3; // A = 4 * ceil(DstLeft/4)
  1291. B = (DstRight ) & ~3; // B = 4 * floor(DstRight/4)
  1292. if (B < A)
  1293. {
  1294. if ((DstLeft & 3) == 1)
  1295. {
  1296. jSrc = *pjSrc++;
  1297. if (jSrc & 15) // is gray pixel zero?
  1298. {
  1299. *pjDstIn = ajIndex[jSrc & 15]; // no, modify dest
  1300. }
  1301. pjDstIn++;
  1302. }
  1303. if ((DstRight & 3) == 3)
  1304. {
  1305. if (jSrc = *pjSrcIn >> 4)
  1306. {
  1307. *pjDstIn = ajIndex[jSrc];
  1308. }
  1309. }
  1310. }
  1311. else
  1312. {
  1313. cPreamble = A - DstLeft;
  1314. cMiddle = (B - A)/4;
  1315. cPostamble = DstRight - B;
  1316. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  1317. {
  1318. int cLast;
  1319. int i;
  1320. pjSrc = pjSrcIn;
  1321. pjDst = pjDstIn;
  1322. switch (cPreamble)
  1323. {
  1324. case 3:
  1325. jSrc = *pjSrc++;
  1326. if (jSrc & 15)
  1327. {
  1328. *pjDst = ajIndex[jSrc & 15];
  1329. }
  1330. pjDst++;
  1331. // fall through
  1332. case 2:
  1333. jSrc = *pjSrc;
  1334. if (jSrc >> 4)
  1335. {
  1336. *pjDst = ajIndex[jSrc >> 4];
  1337. }
  1338. pjDst++;
  1339. // fall through
  1340. case 1:
  1341. jSrc = *pjSrc++;
  1342. if (jSrc & 15)
  1343. {
  1344. *pjDst = ajIndex[jSrc & 15];
  1345. }
  1346. pjDst++;
  1347. // fall through
  1348. }
  1349. for (i = 0; i < cMiddle ; i++)
  1350. {
  1351. jSrc = *pjSrc++;
  1352. if (jSrc >> 4)
  1353. {
  1354. *pjDst = ajIndex[jSrc >> 4];
  1355. }
  1356. pjDst++;
  1357. if (jSrc & 15)
  1358. {
  1359. *pjDst = ajIndex[jSrc & 15];
  1360. }
  1361. pjDst++;
  1362. jSrc = *pjSrc++;
  1363. if (jSrc >> 4)
  1364. {
  1365. *pjDst = ajIndex[jSrc >> 4];
  1366. }
  1367. pjDst++;
  1368. if (jSrc & 15)
  1369. {
  1370. *pjDst = ajIndex[jSrc & 15];
  1371. }
  1372. pjDst++;
  1373. }
  1374. if (cLast = cPostamble)
  1375. {
  1376. cLast -= 1;
  1377. jSrc = *pjSrc++;
  1378. if (jSrc >> 4)
  1379. {
  1380. *pjDst = ajIndex[jSrc >> 4];
  1381. }
  1382. pjDst++;
  1383. if (cLast)
  1384. {
  1385. cLast -= 1;
  1386. if (jSrc & 15)
  1387. {
  1388. *pjDst = ajIndex[jSrc & 15];
  1389. }
  1390. pjDst++;
  1391. if (cLast)
  1392. {
  1393. jSrc = *pjSrc;
  1394. if (jSrc >> 4)
  1395. {
  1396. *pjDst = ajIndex[jSrc >> 4];
  1397. }
  1398. pjDst++;
  1399. if (jSrc & 15)
  1400. {
  1401. *pjDst = ajIndex[jSrc & 15];
  1402. }
  1403. pjDst++;
  1404. }
  1405. }
  1406. }
  1407. }
  1408. }
  1409. }
  1410. #endif
  1411. /******************************Public*Routine******************************\
  1412. * *
  1413. * Routine Name *
  1414. * *
  1415. * vSrcOpaqCopyS4D16 *
  1416. * *
  1417. * Routine Description: *
  1418. * *
  1419. * Arguments: *
  1420. * *
  1421. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  1422. * SrcLeft - left (starting) pixel in src rectangle *
  1423. * DeltaSrcIn - bytes from one src scan line to next *
  1424. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  1425. * DstLeft - left(first) dst pixel *
  1426. * DstRight - right(last) dst pixel *
  1427. * DeltaDstIn - bytes from one Dst scan line to next *
  1428. * cy - number of scan lines *
  1429. * uF - Foreground color *
  1430. * uB - Background color *
  1431. * pS - pointer to destination SURFACE *
  1432. * *
  1433. * Return Value: *
  1434. * *
  1435. * None *
  1436. * *
  1437. \**************************************************************************/
  1438. VOID
  1439. vSrcOpaqCopyS4D16(
  1440. PBYTE pjSrcIn,
  1441. LONG SrcLeft,
  1442. LONG DeltaSrcIn,
  1443. PBYTE pjDstIn,
  1444. LONG DstLeft,
  1445. LONG DstRight,
  1446. LONG DeltaDstIn,
  1447. LONG cy,
  1448. ULONG uF,
  1449. ULONG uB,
  1450. SURFACE *pS
  1451. )
  1452. {
  1453. int cPreamble, cMiddle, cPostamble, A, B;
  1454. USHORT *aus; // array of 16 possible colors
  1455. USHORT *pus; // convenient pointer into the color array
  1456. //
  1457. // If filling the color table in aus
  1458. // turns out to be time consuming we could cache the table
  1459. // off of the FONTOBJ and check to see if the foreground and
  1460. // background colors have not changed since the last time.
  1461. //
  1462. #if DBG
  1463. if (gflFontDebug & DEBUG_AA)
  1464. {
  1465. DbgPrint(
  1466. "vSrcOpaqCopyS4D16(\n"
  1467. " pjSrcIn = %-#x\n"
  1468. " SrcLeft = %-#x\n"
  1469. " pjDstIn = %-#x\n"
  1470. " DstLeft = %-#x\n"
  1471. " DstRight = %-#x\n"
  1472. " DeltaDstIn = %-#x\n"
  1473. " cy = %-#x\n"
  1474. " uF = %-#x\n"
  1475. " uB = %-#x\n"
  1476. " pS = %-#x\n"
  1477. , pjSrcIn
  1478. , SrcLeft
  1479. , pjDstIn
  1480. , DstLeft
  1481. , DstRight
  1482. , DeltaDstIn
  1483. , cy
  1484. , uF
  1485. , uB
  1486. , pS
  1487. );
  1488. DbgBreakPoint();
  1489. }
  1490. #endif
  1491. aus = (USHORT*) pvFillOpaqTable(sizeof(*aus), uF, uB, pS);
  1492. A = (DstLeft + 1) & ~1;
  1493. B = (DstRight ) & ~1;
  1494. pjSrcIn += SrcLeft/2;
  1495. pjDstIn += DstLeft * sizeof(USHORT);
  1496. cPreamble = A - DstLeft;
  1497. cMiddle = (B - A) / 2;
  1498. cPostamble = DstRight - B;
  1499. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  1500. {
  1501. int i;
  1502. BYTE jSrc;
  1503. BYTE *pjSrc = pjSrcIn;
  1504. USHORT *pusDst = (USHORT*) pjDstIn;
  1505. if (cPreamble)
  1506. {
  1507. jSrc = *pjSrc++;
  1508. *pusDst++ = aus[jSrc & 15];
  1509. }
  1510. for (i = 0; i < cMiddle; i++)
  1511. {
  1512. jSrc = *pjSrc++;
  1513. *pusDst++ = aus[jSrc >> 4];
  1514. *pusDst++ = aus[jSrc & 15];
  1515. }
  1516. if (cPostamble)
  1517. {
  1518. jSrc = *pjSrc;
  1519. *pusDst = aus[jSrc >> 4];
  1520. }
  1521. }
  1522. }
  1523. /******************************Public*Routine******************************\
  1524. * *
  1525. * Routine Name *
  1526. * *
  1527. * vSrcTranCopyS4D16 *
  1528. * *
  1529. * Routine Description: *
  1530. * *
  1531. * Arguments: *
  1532. * *
  1533. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  1534. * SrcLeft - left (starting) pixel in src rectangle *
  1535. * DeltaSrcIn - bytes from one src scan line to next *
  1536. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  1537. * DstLeft - left(first) dst pixel *
  1538. * DstRight - right(last) dst pixel *
  1539. * DeltaDstIn - bytes from one Dst scan line to next *
  1540. * cy - number of scan lines *
  1541. * uF - Foreground color *
  1542. * uB - Background color *
  1543. * pS - pointer to the FINAL destination SURFACE *
  1544. * *
  1545. * Return Value: *
  1546. * *
  1547. * None *
  1548. * *
  1549. \**************************************************************************/
  1550. VOID
  1551. vSrcTranCopyS4D16(
  1552. PBYTE pjSrcIn,
  1553. LONG SrcLeft,
  1554. LONG DeltaSrcIn,
  1555. PBYTE pjDstIn,
  1556. LONG DstLeft,
  1557. LONG DstRight,
  1558. LONG DeltaDstIn,
  1559. LONG cy,
  1560. ULONG uF,
  1561. ULONG uB,
  1562. SURFACE *pS
  1563. )
  1564. {
  1565. ULONG flRed, cRedRight, uRedF, flRedRight;
  1566. ULONG flGre, cGreRight, uGreF, flGreRight;
  1567. ULONG flBlu, cBluRight, uBluF, flBluRight;
  1568. ULONG uT, dT, u;
  1569. CONST ULONG *aul;
  1570. int cPreamble, cMiddle, cPostamble, A, B;
  1571. BYTE j;
  1572. XEPALOBJ xpo;
  1573. if(pS->pPal == NULL)
  1574. {
  1575. PDEVOBJ pdo(pS->hdev());
  1576. xpo.ppalSet(pdo.ppalSurf());
  1577. }
  1578. else
  1579. {
  1580. xpo.ppalSet(pS->pPal);
  1581. }
  1582. ASSERTGDI(xpo.bValid(), "Invalid XEPALOBJ" );
  1583. if (xpo.bIsBitfields())
  1584. {
  1585. flRed = xpo.flRed(); // masks red bits
  1586. cRedRight = xpo.cRedRight();
  1587. flGre = xpo.flGre(); // masks green bits
  1588. cGreRight = xpo.cGreRight();
  1589. flBlu = xpo.flBlu(); // masks blu bits
  1590. cBluRight = xpo.cBluRight();
  1591. }
  1592. else if (xpo.bIsRGB())
  1593. {
  1594. WARNING("16 bit-RGB -- assuming 5+5+5\n");
  1595. flRed = 0x001f;
  1596. cRedRight = 0;
  1597. flGre = 0x03e0;
  1598. cGreRight = 5;
  1599. flBlu = 0x7c00;
  1600. cBluRight = 10;
  1601. }
  1602. else if (xpo.bIsBGR())
  1603. {
  1604. WARNING("16 bit-BGR -- assuming 5+5+5\n");
  1605. flRed = 0x7c00;
  1606. cRedRight = 10;
  1607. flGre = 0x03e0;
  1608. cGreRight = 5;
  1609. flBlu = 0x001f;
  1610. cBluRight = 0;
  1611. }
  1612. else
  1613. {
  1614. RIP("unsuported palette format\n");
  1615. }
  1616. uRedF = (uF & flRed) >> cRedRight;
  1617. flRedRight = flRed >> cRedRight;
  1618. uGreF = (uF & flGre) >> cGreRight;
  1619. flGreRight = flGre >> cGreRight;
  1620. uBluF = (uF & flBlu) >> cBluRight;
  1621. flBluRight = flBlu >> cBluRight;
  1622. #if DBG
  1623. if (gflFontDebug & DEBUG_AA)
  1624. {
  1625. DbgPrint(
  1626. "vSrcTranCopyS4D16(\n"
  1627. " pjSrcIn = %-#x\n"
  1628. " SrcLeft = %d\n"
  1629. " DeltaSrcIn = %d\n"
  1630. " pjDstIn = %-#x\n"
  1631. " DstLeft = %d\n"
  1632. " DstRight = %d\n"
  1633. " DeltaDstIn = %d\n"
  1634. " cy = %d\n"
  1635. " uF = %-#x\n"
  1636. " uB = %-#x\n"
  1637. " pS = %-#x\n"
  1638. , pjSrcIn
  1639. , SrcLeft
  1640. , DeltaSrcIn
  1641. , pjDstIn
  1642. , DstLeft
  1643. , DstRight
  1644. , DeltaDstIn
  1645. , cy
  1646. , uF
  1647. , uB
  1648. , pS
  1649. );
  1650. DbgPrint(
  1651. " flRed = %-#x\n"
  1652. " cRedRight = %d\n"
  1653. " uRedF = %-#x\n"
  1654. " flRedRight = %-#x\n"
  1655. , flRed, cRedRight, uRedF, flRedRight
  1656. );
  1657. DbgPrint(
  1658. " flGre = %-#x\n"
  1659. " cGreRight = %d\n"
  1660. " uGreF = %-#x\n"
  1661. " flGreRight = %-#x\n"
  1662. , flGre, cGreRight, uGreF, flGreRight
  1663. );
  1664. DbgPrint(
  1665. " flBlu = %-#x\n"
  1666. " cBluRight = %d\n"
  1667. " uBluF = %-#x\n"
  1668. " flBluRight = %-#x\n"
  1669. , flBlu, cBluRight, uBluF, flBluRight
  1670. );
  1671. DbgBreakPoint();
  1672. }
  1673. #endif
  1674. /*****************************************************************************
  1675. * *
  1676. * The CCC macro blends forground and background colors of a single color *
  1677. * channel. Gamma correction is taken into account using an approximate *
  1678. * correction scheme. uB contains all three background colors. We first *
  1679. * mask off the bits of interest and then shift them down until the *
  1680. * least significant color bit resides at the lowest bit of the dword. *
  1681. * The answer is placed in uT ("temporary ULONG"). This must be done for *
  1682. * each pixel in the destination. The same thing has been done for the *
  1683. * each of the forground color channels and placed in uRedF, uGreF, *
  1684. * and uBluF. These values do not change from pixel to pixel and so the *
  1685. * calculation of these down shifted forground color channel values is *
  1686. * done up front before the loop. Then for each color channel we *
  1687. * calculate the difference between the down-shifted forground- and *
  1688. * background color channels and place the answer in dT ("temporary *
  1689. * difference"). The approximate gamma correction is done in the *
  1690. * following manner: If the background color value is smaller than *
  1691. * the foreground color value then the approximate correction is: *
  1692. * *
  1693. * (c_f >= c_b): *
  1694. * *
  1695. * c = c_b + alpha_k ^ (1/gamma) * (c_f - c_b) *
  1696. * *
  1697. * (c_f <= c_b): *
  1698. * *
  1699. * c = c_b + (1 - (1 - alpha_k)^(1/gamma)) * (c_f - c_b) *
  1700. * *
  1701. * where *
  1702. * *
  1703. * c := blended color *
  1704. * c_b := background color *
  1705. * c_f := foreground color *
  1706. * alpha_k := k'th blending fraction = k == 0 ? 0 : (k+1)/16; *
  1707. * gamma := 2.33 *
  1708. * *
  1709. * I have storred all sixteen values of alpha_k ^ (1/gamma) in 16.16 *
  1710. * representation in an array ULONG aulB[16] and I have storred the *
  1711. * values of 1 - (1 - alpha_k)^(1/gamma) in aulIB[k] *
  1712. * *
  1713. * Thus the blended color value is *
  1714. * *
  1715. * (c_f >= c_b): *
  1716. * *
  1717. * c = (2^16 * c_b + aulB[k] * (c_f - c_b)) / 2^16 *
  1718. * *
  1719. * *
  1720. * (c_f <= c_b): *
  1721. * *
  1722. * c = (2^16 * c_b + aulB[15-k] * (c_f - c_b)) / 2^16 *
  1723. * Instead of accessing aulB[15-k], I access aulIB which has *
  1724. * aulIB[k] = aulB[15-k] *
  1725. * In the macro below, I actually blend the down-shifted color *
  1726. * channel values and then shift the answer up and mask it (the *
  1727. * mask shouldn't be necessary, but this is a precaution). *
  1728. * *
  1729. *****************************************************************************/
  1730. #define CCC(Color,jj) \
  1731. uT = (uB & fl##Color) >> c##Color##Right; \
  1732. dT = u##Color##F - uT; \
  1733. aul = ((LONG) dT < 0) ? aulIB : aulB; \
  1734. u |= (((dT * aul[jj] + (uT << 16)) >> 16) << c##Color##Right) & fl##Color
  1735. /******************************************************************************
  1736. * *
  1737. * The SETCOLOR macro looks at the blending value. If it is zero then *
  1738. * the destination pixel does not change and we do nothing. If the blending *
  1739. * value is 15 then the destination pixel should take the forground color *
  1740. * , no blending is necessary. If the blending value is one of 1..14 then *
  1741. * all three color channels are blended and added together. *
  1742. * *
  1743. ******************************************************************************/
  1744. #define SETCOLOR(jj) \
  1745. if (j = (jj)) \
  1746. { \
  1747. if (j == 15) \
  1748. { \
  1749. u = uF; \
  1750. } \
  1751. else \
  1752. { \
  1753. u = 0; \
  1754. uB = (ULONG) *pusDst; \
  1755. CCC(Red,j); \
  1756. CCC(Gre,j); \
  1757. CCC(Blu,j); \
  1758. } \
  1759. *pusDst = (USHORT) u; \
  1760. } \
  1761. pusDst++
  1762. /*********************************************************************
  1763. * *
  1764. * Each pixel takes 16-bits, half of a DWORD. I will separate *
  1765. * each scan into three sections: the "preamble", the *
  1766. * "middle", and the "postamble". The preamble are the set of *
  1767. * pixels that occur before the first 32-bit boundary in the *
  1768. * destination. Either a pixel starts on a DWORD or it doesn't. *
  1769. * Therefore there can be at most one pixel in the preamble. *
  1770. * The middle section starts and ends on a 32-bit boundary. *
  1771. * The postamble starts on a 32-bit boundary but ends on an *
  1772. * address that is not 32-bit aligned. There can be at most *
  1773. * one pixel in the postamble. *
  1774. * *
  1775. * A = x-coord of pixel starting on the lowest *
  1776. * 32-bit aligned address in the scan *
  1777. * *
  1778. * = 2 (pixels/dword) *
  1779. * * ceiling (16 (bits/pixel) * left / 32 (bits/dword)) *
  1780. * *
  1781. * = 2 * ceiling( left / 2 ) *
  1782. * *
  1783. * = 2 * floor((left + 1) / 2) *
  1784. * *
  1785. * = (left + 1) & ~1; *
  1786. * *
  1787. * *
  1788. * B = x-coord of pixel starting at the highest *
  1789. * 32-bit aligned address in the scan *
  1790. * *
  1791. * = 2 * floor( right / 2) *
  1792. * *
  1793. * = right & ~1 *
  1794. * *
  1795. * *
  1796. * cPreamble = # pixels in preamble *
  1797. * cPostamble = # pixels in postamble *
  1798. * *
  1799. * Each nyble of the gray 4-bpp source bitmap corresponds to a *
  1800. * pixel in the destination. The pixels of the scan do not *
  1801. * start on the left edge of the gray 4-bpp bitmap, they are *
  1802. * indented by SrcLeft pixels. The reason is that the gray *
  1803. * bitmap was aligned so that the initial starting address *
  1804. * of the gray bitmap started at a position corresponding to *
  1805. * a 32-bit aligned address in the destination. Thus there *
  1806. * is a relationship between cPreamble and SrcLeft. In any *
  1807. * case we have to move the pointer to the first source pixel *
  1808. * of interest inward away from the left edge of the gray *
  1809. * source bitmap. Since we move pointers in BYTE increments *
  1810. * we must convert the number of pixels (SrcLeft), each *
  1811. * of which corresponds to an nyble to a count of bytes. The *
  1812. * conversion is easy *
  1813. * *
  1814. * source shift in bytes = floor(SrcLeft/2) *
  1815. * *
  1816. * Similarly, the pointer to the destination must be indented *
  1817. * by the offset of the x-coordinate of the destination *
  1818. * rectangle and thus pjDstIn is shifted *
  1819. * *
  1820. *********************************************************************/
  1821. A = (DstLeft + 1) & ~1;
  1822. B = (DstRight ) & ~1;
  1823. cPreamble = A - DstLeft;
  1824. cMiddle = (B - A)/2;
  1825. cPostamble = DstRight - B;
  1826. pjSrcIn += SrcLeft / 2;
  1827. pjDstIn += DstLeft * sizeof(USHORT);
  1828. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  1829. {
  1830. int i;
  1831. BYTE jSrc;
  1832. BYTE *pjSrc = pjSrcIn;
  1833. USHORT *pusDst = (USHORT*) pjDstIn;
  1834. if (cPreamble)
  1835. {
  1836. jSrc = *pjSrc;
  1837. SETCOLOR(jSrc & 15);
  1838. pjSrc++;
  1839. }
  1840. for (i = 0; i < cMiddle; i++)
  1841. {
  1842. jSrc = *pjSrc;
  1843. SETCOLOR(jSrc >> 4);
  1844. SETCOLOR(jSrc & 15);
  1845. pjSrc++;
  1846. }
  1847. if (cPostamble)
  1848. {
  1849. SETCOLOR(*pjSrc >> 4);
  1850. }
  1851. }
  1852. #undef SETCOLOR
  1853. #undef CCC
  1854. }
  1855. /******************************Public*Routine******************************\
  1856. * *
  1857. * Routine Name *
  1858. * *
  1859. * vSrcOpaqCopyS4D24 *
  1860. * *
  1861. * Routine Description: *
  1862. * *
  1863. * Arguments: *
  1864. * *
  1865. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  1866. * SrcLeft - left (starting) pixel in src rectangle *
  1867. * DeltaSrcIn - bytes from one src scan line to next *
  1868. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  1869. * DstLeft - left(first) dst pixel *
  1870. * DstRight - right(last) dst pixel *
  1871. * DeltaDstIn - bytes from one Dst scan line to next *
  1872. * cy - number of scan lines *
  1873. * uF - Foreground color *
  1874. * uB - Background color *
  1875. * pS - pointer to destination SURFACE *
  1876. * *
  1877. * Return Value: *
  1878. * *
  1879. * None *
  1880. * *
  1881. \**************************************************************************/
  1882. VOID
  1883. vSrcOpaqCopyS4D24(
  1884. PBYTE pjSrcIn,
  1885. LONG SrcLeft,
  1886. LONG DeltaSrcIn,
  1887. PBYTE pjDstIn,
  1888. LONG DstLeft,
  1889. LONG DstRight,
  1890. LONG DeltaDstIn,
  1891. LONG cy,
  1892. ULONG uF,
  1893. ULONG uB,
  1894. SURFACE *pS
  1895. )
  1896. {
  1897. int A; // position of first 32-bit aligned pixel
  1898. int B; // position of last 32-bit aligned pixel
  1899. int cPreamble; // The preamble is the set of pixeles
  1900. // that you need to go through to get
  1901. // nearest 32-bit boundary in the destination
  1902. int cMiddle; // This is the number of interations
  1903. // that are done in the middle section
  1904. // in which we are guaranteed 32-bit alignment. Each time through
  1905. // the loop, we use 2 source bytes which corresponds to 4 pixels.
  1906. // In this case of 24-bits per destination pixel, this means that
  1907. // each itteration of the loop affects 3 DWORD's of the destination.
  1908. // This means that cMiddle = (#destination DWORD's)/3 in the
  1909. // middle (32-bit aligned) section.
  1910. int cPostamble; // The postamble is the set of pixels
  1911. // that remain after the last 32-bit
  1912. // boundary in the destination. Thus number is can be 0, 1, or 2.
  1913. ULONG *aul; // a cache of the 16 possible 24-bit
  1914. // colors that can be seen on the
  1915. // destination surface.
  1916. #if DBG
  1917. if (gflFontDebug & DEBUG_AA)
  1918. {
  1919. DbgPrint(
  1920. "vSrcOpaqCopyS4D24(\n"
  1921. " PBYTE pjSrcIn = %-#x\n"
  1922. " LONG SrcLeft = %d\n"
  1923. " LONG DeltaSrcIn = %d\n"
  1924. " PBYTE pjDstIn = %-#x\n"
  1925. " LONG DstLeft = %d\n"
  1926. " LONG DstRight = %d\n"
  1927. " LONG DeltaDstIn = %d\n"
  1928. " LONG cy = %d\n"
  1929. " ULONG uF = %-#x\n"
  1930. " ULONG uB = %-#x\n"
  1931. " SURFACE *pS = %-#x\n"
  1932. , pjSrcIn
  1933. , SrcLeft
  1934. , DeltaSrcIn
  1935. , pjDstIn
  1936. , DstLeft
  1937. , DstRight
  1938. , DeltaDstIn
  1939. , cy
  1940. , uF
  1941. , uB
  1942. , pS
  1943. );
  1944. DbgBreakPoint();
  1945. }
  1946. #endif
  1947. aul = (ULONG*) pvFillOpaqTable(sizeof(*aul), uF, uB, pS);
  1948. pjSrcIn += SrcLeft / 2; // 2 pixels per src byte
  1949. pjDstIn += DstLeft * 3; // 3 bytes per dest pixel
  1950. A = (DstLeft + 3) & ~3; // round up to nearest multiple of 4
  1951. B = (DstRight ) & ~3; // round down to nearest multiple of 4
  1952. #if DBG
  1953. if (gflFontDebug & DEBUG_AA)
  1954. {
  1955. DbgPrint(
  1956. "\n"
  1957. " pjSrcIn = %-#x\n"
  1958. " pjDstIn = %-#x\n"
  1959. " A = %d\n"
  1960. " B = %d\n"
  1961. , pjSrcIn
  1962. , pjDstIn
  1963. , A
  1964. , B
  1965. );
  1966. DbgBreakPoint();
  1967. }
  1968. #endif
  1969. if (A <= B)
  1970. {
  1971. cPreamble = A - DstLeft; // # pixels in preamble
  1972. cMiddle = (B - A) / 4; // each loop does 4 pixels
  1973. cPostamble = DstRight - B; // # pixels in postample
  1974. #if DBG
  1975. if (gflFontDebug & DEBUG_AA)
  1976. {
  1977. DbgPrint(
  1978. " cPreamble = %d\n"
  1979. " cMiddle = %d\n"
  1980. " cPostamble = %d\n"
  1981. , cPreamble, cMiddle, cPostamble
  1982. );
  1983. DbgBreakPoint();
  1984. }
  1985. #endif
  1986. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  1987. {
  1988. int i;
  1989. BYTE *ajSrc; // points directly into the gamma correction table
  1990. ULONG *pul;
  1991. BYTE *pjSrc = pjSrcIn;
  1992. BYTE *pjDst = pjDstIn;
  1993. switch (cPreamble)
  1994. {
  1995. case 3:
  1996. ajSrc = (BYTE*) & (aul[*pjSrc & 15]);
  1997. *pjDst++ = *ajSrc++;
  1998. *pjDst++ = *ajSrc++;
  1999. *pjDst++ = *ajSrc;
  2000. pjSrc++;
  2001. // fall through
  2002. case 2:
  2003. ajSrc = (BYTE*) & (aul[*pjSrc >> 4]);
  2004. *pjDst++ = *ajSrc++;
  2005. *pjDst++ = *ajSrc++;
  2006. *pjDst++ = *ajSrc;
  2007. // fall through
  2008. case 1:
  2009. ajSrc = (BYTE*) & (aul[*pjSrc & 15]);
  2010. *pjDst++ = *ajSrc++;
  2011. *pjDst++ = *ajSrc++;
  2012. *pjDst++ = *ajSrc;
  2013. pjSrc++;
  2014. case 0:
  2015. ;
  2016. }
  2017. for (pul = (ULONG*) pjDst, i = 0; i < cMiddle; i++)
  2018. {
  2019. /*****************************************************
  2020. * Each time through the loop four pixels are *
  2021. * processed (3 DWORD's in the destination, 2 *
  2022. * bytes in the source glyph.) *
  2023. *****************************************************/
  2024. ULONG c0, c1, c2, c3;
  2025. BYTE j0,j1;
  2026. ASSERTGDI(!((ULONG_PTR) pjDst & 3),"bad alignment\n");
  2027. j0 = *pjSrc++;
  2028. j1 = *pjSrc++;
  2029. c0 = aul[j0 >> 4];
  2030. c1 = aul[j0 & 15];
  2031. c2 = aul[j1 >> 4];
  2032. c3 = aul[j1 & 15];
  2033. *pul++ = (c0 ) + (c1 << 24);
  2034. *pul++ = (c1 >> 8) + (c2 << 16);
  2035. *pul++ = (c2 >> 16) + (c3 << 8);
  2036. }
  2037. pjDst = (BYTE*) pul;
  2038. if (i = cPostamble)
  2039. {
  2040. /*****************************************************
  2041. * I do the postamble a byte at a time so that I *
  2042. * don't overwrite pixels beyond the scan. If I *
  2043. * wrote a DWORD at a time, then I would have to *
  2044. * do some tricky masking. *
  2045. *****************************************************/
  2046. i--;
  2047. ajSrc = (BYTE*) & (aul[*pjSrc >> 4]);
  2048. *pjDst++ = *ajSrc++;
  2049. *pjDst++ = *ajSrc++;
  2050. *pjDst++ = *ajSrc;
  2051. if (i)
  2052. {
  2053. i--;
  2054. ajSrc = (BYTE*) & (aul[*pjSrc & 15]);
  2055. *pjDst++ = *ajSrc++;
  2056. *pjDst++ = *ajSrc++;
  2057. *pjDst++ = *ajSrc;
  2058. pjSrc++;
  2059. if (i) {
  2060. ajSrc = (BYTE*) & (aul[*pjSrc >> 4]);
  2061. *pjDst++ = *ajSrc++;
  2062. *pjDst++ = *ajSrc++;
  2063. *pjDst++ = *ajSrc;
  2064. }
  2065. }
  2066. }
  2067. }
  2068. }
  2069. else
  2070. {
  2071. /***************************************************************
  2072. * If the text bitmap is narrow (3 wide or less) then *
  2073. * it is possible to have B < A. There are three such cases: *
  2074. * *
  2075. * 1) DstLeft & 3 == 2 AND DstLeft + 1 == DstRight *
  2076. * 1) DstLeft & 3 == 1 AND DstLeft + 1 == DstRight *
  2077. * 2) DstLeft & 3 == 1 AND DstLeft + 2 == DstRight *
  2078. * *
  2079. * I shall treat each of these as a special case *
  2080. ***************************************************************/
  2081. ASSERTGDI(B < A, "A <= B");
  2082. BYTE *ajSrc; // points directly into the gamma correction table
  2083. BYTE *pjDst = pjDstIn;
  2084. BYTE *pjSrc = pjSrcIn;
  2085. #if DBG
  2086. if (gflFontDebug & DEBUG_AA)
  2087. {
  2088. DbgPrint(
  2089. " SPECIAL CASE: A < B\n"
  2090. " DstLeft & 3 = %d\n"
  2091. , DstLeft & 3
  2092. );
  2093. DbgBreakPoint();
  2094. }
  2095. #endif
  2096. switch (DstLeft & 3)
  2097. {
  2098. case 0:
  2099. RIP("DstLeft & 3 == 0");
  2100. break;
  2101. case 1:
  2102. /********************************************************
  2103. * *
  2104. * H H H L L L H H H L L L *
  2105. * +---------------+---------------+---------------+ *
  2106. * | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 | *
  2107. * +---------------+---------------+---------------+ *
  2108. * X X X *
  2109. * ^ *
  2110. * | *
  2111. * pjDst *
  2112. * *
  2113. ********************************************************/
  2114. // copy three bytes from the opaque color table
  2115. ajSrc = (BYTE*) & (aul[*pjSrc & 15]);
  2116. *pjDst++ = *ajSrc++;
  2117. *pjDst++ = *ajSrc++;
  2118. *pjDst++ = *ajSrc;
  2119. if (DstLeft + 1 == DstRight)
  2120. break;
  2121. pjSrc++; // done with this source byte
  2122. // fall through
  2123. case 2:
  2124. /*********************************************************
  2125. * *
  2126. * H H H L L L H H H L L L *
  2127. * +---------------+---------------+---------------+ *
  2128. * | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 | *
  2129. * +---------------+---------------+---------------+ *
  2130. * X X X *
  2131. * ^ *
  2132. * | *
  2133. * pjDst *
  2134. * *
  2135. *********************************************************/
  2136. // copy three bytes from the opaque color table
  2137. ajSrc = (BYTE*) & (aul[*pjSrc >> 4]);
  2138. *pjDst++ = *ajSrc++;
  2139. *pjDst++ = *ajSrc++;
  2140. *pjDst = *ajSrc;
  2141. break;
  2142. }
  2143. }
  2144. }
  2145. /******************************Public*Routine******************************\
  2146. * *
  2147. * Routine Name *
  2148. * *
  2149. * vSrcTranCopyS4D24 *
  2150. * *
  2151. * Routine Description: *
  2152. * *
  2153. * Arguments: *
  2154. * *
  2155. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  2156. * SrcLeft - left (starting) pixel in src rectangle *
  2157. * DeltaSrcIn - bytes from one src scan line to next *
  2158. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  2159. * DstLeft - left(first) dst pixel *
  2160. * DstRight - right(last) dst pixel *
  2161. * DeltaDstIn - bytes from one Dst scan line to next *
  2162. * cy - number of scan lines *
  2163. * uF - Foreground color *
  2164. * uB - Background color *
  2165. * pS - pointer to destination SURFACE *
  2166. * *
  2167. * Return Value: *
  2168. * *
  2169. * None *
  2170. * *
  2171. \**************************************************************************/
  2172. VOID
  2173. vSrcTranCopyS4D24(
  2174. PBYTE pjSrcIn,
  2175. LONG SrcLeft,
  2176. LONG DeltaSrcIn,
  2177. PBYTE pjDstIn,
  2178. LONG DstLeft,
  2179. LONG DstRight,
  2180. LONG DeltaDstIn,
  2181. LONG cy,
  2182. ULONG uF,
  2183. ULONG uB,
  2184. SURFACE *pS
  2185. )
  2186. {
  2187. #if DBG
  2188. if (gflFontDebug & DEBUG_AA)
  2189. {
  2190. DbgPrint(
  2191. "vSrcTranCopyS4D24(\n"
  2192. " PBYTE pjSrcIn = %-#x\n"
  2193. " LONG SrcLeft = %d\n"
  2194. " LONG DeltaSrcIn = %d\n"
  2195. " PBYTE pjDstIn = %-#x\n"
  2196. " LONG DstLeft = %d\n"
  2197. " LONG DstRight = %d\n"
  2198. " LONG DeltaDstIn = %d\n"
  2199. " LONG cy = %d\n"
  2200. " ULONG uF = %-#x\n"
  2201. " ULONG uB = %-#x\n"
  2202. " SURFACE *pS = %-#x\n"
  2203. " )\n"
  2204. , pjSrcIn
  2205. , SrcLeft
  2206. , DeltaSrcIn
  2207. , pjDstIn
  2208. , DstLeft
  2209. , DstRight
  2210. , DeltaDstIn
  2211. , cy
  2212. , uF
  2213. , uB
  2214. , pS
  2215. );
  2216. DbgBreakPoint();
  2217. }
  2218. #endif
  2219. ULONG flRed, cRedRight, uRedF, flRedRight;
  2220. ULONG flGre, cGreRight, uGreF, flGreRight;
  2221. ULONG flBlu, cBluRight, uBluF, flBluRight;
  2222. ULONG uT, dT, u;
  2223. CONST ULONG *aul;
  2224. int cPreamble, cMiddle, cPostamble, A, B;
  2225. BYTE j;
  2226. XEPALOBJ xpo;
  2227. if(pS->pPal == NULL)
  2228. {
  2229. PDEVOBJ pdo(pS->hdev());
  2230. xpo.ppalSet(pdo.ppalSurf());
  2231. }
  2232. else
  2233. {
  2234. xpo.ppalSet(pS->pPal);
  2235. }
  2236. ASSERTGDI(xpo.bValid(), "Invalid XEPALOBJ" );
  2237. if (xpo.bIsBitfields())
  2238. {
  2239. flRed = xpo.flRed(); // masks red bits
  2240. cRedRight = xpo.cRedRight();
  2241. flGre = xpo.flGre(); // masks green bits
  2242. cGreRight = xpo.cGreRight();
  2243. flBlu = xpo.flBlu(); // masks blu bits
  2244. cBluRight = xpo.cBluRight();
  2245. }
  2246. else if (xpo.bIsRGB())
  2247. {
  2248. // assuming 8+8+8
  2249. flRed = 0x0000ff;
  2250. cRedRight = 0;
  2251. flGre = 0x00ff00;
  2252. cGreRight = 8;
  2253. flBlu = 0xff0000;
  2254. cBluRight = 16;
  2255. }
  2256. else if (xpo.bIsBGR())
  2257. {
  2258. // assuming 8+8+8
  2259. flRed = 0xff0000;
  2260. cRedRight = 16;
  2261. flGre = 0x00ff00;
  2262. cGreRight = 8;
  2263. flBlu = 0x0000ff;
  2264. cBluRight = 0;
  2265. }
  2266. else
  2267. {
  2268. RIP("unsuported palette format\n");
  2269. }
  2270. uRedF = (uF & flRed) >> cRedRight;
  2271. flRedRight = flRed >> cRedRight;
  2272. uGreF = (uF & flGre) >> cGreRight;
  2273. flGreRight = flGre >> cGreRight;
  2274. uBluF = (uF & flBlu) >> cBluRight;
  2275. flBluRight = flBlu >> cBluRight;
  2276. #if DBG
  2277. if (gflFontDebug & DEBUG_AA)
  2278. {
  2279. DbgPrint(
  2280. " flRed = %-#x\n"
  2281. " cRedRight = %d\n"
  2282. " uRedF = %-#x\n"
  2283. " flRedRight = %-#x\n"
  2284. , flRed, cRedRight, uRedF, flRedRight
  2285. );
  2286. DbgPrint(
  2287. " flGre = %-#x\n"
  2288. " cGreRight = %d\n"
  2289. " uGreF = %-#x\n"
  2290. " flGreRight = %-#x\n"
  2291. , flGre, cGreRight, uGreF, flGreRight
  2292. );
  2293. DbgPrint(
  2294. " flBlu = %-#x\n"
  2295. " cBluRight = %d\n"
  2296. " uBluF = %-#x\n"
  2297. " flBluRight = %-#x\n"
  2298. , flBlu, cBluRight, uBluF, flBluRight
  2299. );
  2300. DbgBreakPoint();
  2301. }
  2302. #endif
  2303. /******************************************************************************
  2304. * *
  2305. * See the discussion of the CCC macro in vSrcTranCopyS4D16() *
  2306. * *
  2307. * *
  2308. */
  2309. #define CCC(Color,jj) \
  2310. uT = (uB & fl##Color) >> c##Color##Right; \
  2311. dT = u##Color##F - uT; \
  2312. aul = ((LONG) dT < 0) ? aulIB : aulB; \
  2313. u |= (((dT * aul[jj] + (uT << 16)) >> 16) \
  2314. << c##Color##Right) & fl##Color
  2315. /* *
  2316. * *
  2317. * *
  2318. /******************************************************************************/
  2319. /******************************************************************************
  2320. * *
  2321. * The SETCOLOR macro looks at the blending value. If it is zero then *
  2322. * the destination pixel does not change and we do nothing. If the blending *
  2323. * value is 15 then the destination pixel should take the forground color *
  2324. * , no blending is necessary. If the blending value is one of 1..14 then *
  2325. * all three color channels are blended and added together. *
  2326. * *
  2327. * */
  2328. #define SETCOLOR(jj) \
  2329. if (j = (jj)) \
  2330. { \
  2331. if (j == 15) \
  2332. { \
  2333. u = uF; \
  2334. } \
  2335. else \
  2336. { \
  2337. u = 0; \
  2338. *(((BYTE*) & uB)+0) = *(pjDst+0); \
  2339. *(((BYTE*) & uB)+1) = *(pjDst+1); \
  2340. *(((BYTE*) & uB)+2) = *(pjDst+2); \
  2341. CCC(Red,j); \
  2342. CCC(Gre,j); \
  2343. CCC(Blu,j); \
  2344. } \
  2345. *(pjDst+0) = *(((BYTE*) & u)+0); \
  2346. *(pjDst+1) = *(((BYTE*) & u)+1); \
  2347. *(pjDst+2) = *(((BYTE*) & u)+2); \
  2348. } \
  2349. pjDst += 3
  2350. /* *
  2351. * *
  2352. * *
  2353. /******************************************************************************/
  2354. A = (DstLeft + 3) & ~3;
  2355. B = (DstRight ) & ~3;
  2356. pjSrcIn += SrcLeft / 2; // 4-bits per source pixel
  2357. pjDstIn += DstLeft * 3; // 24-bits per destination pixel
  2358. if (A <= B)
  2359. {
  2360. cPreamble = A - DstLeft;
  2361. cMiddle = (B - A) / 4;
  2362. cPostamble = DstRight - B;
  2363. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  2364. {
  2365. int i;
  2366. BYTE *pjSrc = pjSrcIn;
  2367. BYTE *pjDst = pjDstIn;
  2368. switch (cPreamble)
  2369. {
  2370. case 3:
  2371. SETCOLOR(*pjSrc & 15);
  2372. pjSrc++;
  2373. case 2:
  2374. SETCOLOR(*pjSrc >> 4);
  2375. case 1:
  2376. SETCOLOR(*pjSrc & 15);
  2377. pjSrc++;
  2378. case 0:
  2379. ;
  2380. }
  2381. ASSERTGDI(!((ULONG_PTR) pjDst & 3),"bad alignment\n");
  2382. for (i = 0; i < cMiddle; i++)
  2383. {
  2384. SETCOLOR(*pjSrc >> 4);
  2385. SETCOLOR(*pjSrc & 15);
  2386. pjSrc++;
  2387. SETCOLOR(*pjSrc >> 4);
  2388. SETCOLOR(*pjSrc & 15);
  2389. pjSrc++;
  2390. }
  2391. if (i = cPostamble)
  2392. {
  2393. SETCOLOR(*pjSrc >> 4);
  2394. i--;
  2395. if (i)
  2396. {
  2397. SETCOLOR(*pjSrc & 15);
  2398. i--;
  2399. if (i)
  2400. {
  2401. pjSrc++;
  2402. SETCOLOR(*pjSrc >> 4);
  2403. }
  2404. }
  2405. }
  2406. }
  2407. }
  2408. else
  2409. {
  2410. /***************************************************************
  2411. * If the text bitmap is narrow (3 wide or less) then *
  2412. * it is possible to have B < A. There are three such cases: *
  2413. * *
  2414. * 1) DstLeft & 3 == 2 AND DstLeft + 1 == DstRight *
  2415. * 1) DstLeft & 3 == 1 AND DstLeft + 1 == DstRight *
  2416. * 2) DstLeft & 3 == 1 AND DstLeft + 2 == DstRight *
  2417. * *
  2418. * I shall treat each of these as a special case *
  2419. ***************************************************************/
  2420. ASSERTGDI(B < A, "A <= B");
  2421. BYTE *ajSrc; // points directly into the gamma correction table
  2422. BYTE *pjDst = pjDstIn;
  2423. BYTE *pjSrc = pjSrcIn;
  2424. #if DBG
  2425. if (gflFontDebug & DEBUG_AA)
  2426. {
  2427. DbgPrint(
  2428. " SPECIAL CASE: A < B\n"
  2429. " DstLeft & 3 = %d\n"
  2430. , DstLeft & 3
  2431. );
  2432. DbgBreakPoint();
  2433. }
  2434. #endif
  2435. switch (DstLeft & 3)
  2436. {
  2437. case 0:
  2438. RIP("DstLeft & 3 == 0");
  2439. break;
  2440. case 1:
  2441. /********************************************************
  2442. * *
  2443. * H H H L L L H H H L L L *
  2444. * +---------------+---------------+---------------+ *
  2445. * | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 | *
  2446. * +---------------+---------------+---------------+ *
  2447. * X X X *
  2448. * ^ *
  2449. * | *
  2450. * pjDst *
  2451. * *
  2452. ********************************************************/
  2453. SETCOLOR(*pjSrc & 15);
  2454. if (DstLeft + 1 == DstRight)
  2455. break;
  2456. pjSrc++; // done with this byte
  2457. // fall through
  2458. case 2:
  2459. /*********************************************************
  2460. * *
  2461. * H H H L L L H H H L L L *
  2462. * +---------------+---------------+---------------+ *
  2463. * | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 | *
  2464. * +---------------+---------------+---------------+ *
  2465. * X X X *
  2466. * ^ *
  2467. * | *
  2468. * pjDst *
  2469. * *
  2470. *********************************************************/
  2471. SETCOLOR(*pjSrc >> 4);
  2472. break;
  2473. }
  2474. }
  2475. #undef SETCOLOR
  2476. #undef CCC
  2477. }
  2478. /******************************Public*Routine******************************\
  2479. * *
  2480. * Routine Name *
  2481. * *
  2482. * vSrcOpaqCopyS4D32 *
  2483. * *
  2484. * Routine Description: *
  2485. * *
  2486. * Arguments: *
  2487. * *
  2488. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  2489. * SrcLeft - left (starting) pixel in src rectangle *
  2490. * DeltaSrcIn - bytes from one src scan line to next *
  2491. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  2492. * DstLeft - left(first) dst pixel *
  2493. * DstRight - right(last) dst pixel *
  2494. * DeltaDstIn - bytes from one Dst scan line to next *
  2495. * cy - number of scan lines *
  2496. * uF - Foreground color *
  2497. * uB - Background color *
  2498. * pS - pointer to destination SURFACE *
  2499. * *
  2500. * Return Value: *
  2501. * *
  2502. * None *
  2503. * *
  2504. \**************************************************************************/
  2505. VOID
  2506. vSrcOpaqCopyS4D32(
  2507. PBYTE pjSrcIn,
  2508. LONG SrcLeft,
  2509. LONG DeltaSrcIn,
  2510. PBYTE pjDstIn,
  2511. LONG DstLeft,
  2512. LONG DstRight,
  2513. LONG DeltaDstIn,
  2514. LONG cy,
  2515. ULONG uF,
  2516. ULONG uB,
  2517. SURFACE *pS
  2518. )
  2519. {
  2520. int A, B, cPreamble, cMiddle, cPostamble;
  2521. ULONG *aul; // array of 16 possible colors
  2522. #if DBG
  2523. if (gflFontDebug & DEBUG_AA)
  2524. {
  2525. DbgPrint(
  2526. "vSrcOpaqCopyS4D32(\n"
  2527. " pjSrcIn = %-#x\n"
  2528. " SrcLeft = %-#x\n"
  2529. " pjDstIn = %-#x\n"
  2530. " DstLeft = %-#x\n"
  2531. " DstRight = %-#x\n"
  2532. " DeltaDstIn = %-#x\n"
  2533. " cy = %-#x\n"
  2534. " uF = %-#x\n"
  2535. " uB = %-#x\n"
  2536. " pS = %-#x\n"
  2537. , pjSrcIn
  2538. , SrcLeft
  2539. , DeltaSrcIn
  2540. , pjDstIn
  2541. , DstLeft
  2542. , DstRight
  2543. , DeltaDstIn
  2544. , cy
  2545. , uF
  2546. , uB
  2547. , pS
  2548. );
  2549. DbgBreakPoint();
  2550. }
  2551. #endif
  2552. aul = (ULONG*) pvFillOpaqTable(sizeof(*aul), uF, uB, pS);
  2553. A = (DstLeft + 1) & ~1;
  2554. B = (DstRight ) & ~1;
  2555. cPreamble = A - DstLeft; // # pixels in preamble
  2556. cMiddle = (B - A)/2;
  2557. cPostamble = DstRight - B; // # pixels in postamble
  2558. pjSrcIn += SrcLeft / 2;
  2559. pjDstIn += DstLeft * sizeof(ULONG);
  2560. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  2561. {
  2562. int i;
  2563. BYTE *pjSrc = pjSrcIn;
  2564. ULONG *pul = (ULONG*) pjDstIn;
  2565. if (cPreamble)
  2566. {
  2567. *pul++ = aul[*pjSrc++ & 15];
  2568. }
  2569. for (i = 0; i < cMiddle; i++)
  2570. {
  2571. BYTE j = *pjSrc++;
  2572. *pul++ = aul[j >> 4];
  2573. *pul++ = aul[j & 15];
  2574. }
  2575. if (cPostamble)
  2576. {
  2577. *pul = aul[*pjSrc >> 4];
  2578. }
  2579. }
  2580. }
  2581. /******************************Public*Routine******************************\
  2582. * *
  2583. * Routine Name *
  2584. * *
  2585. * vSrcTranCopyS4D32 *
  2586. * *
  2587. * Routine Description: *
  2588. * *
  2589. * Arguments: *
  2590. * *
  2591. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  2592. * SrcLeft - left (starting) pixel in src rectangle *
  2593. * DeltaSrcIn - bytes from one src scan line to next *
  2594. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  2595. * DstLeft - left(first) dst pixel *
  2596. * DstRight - right(last) dst pixel *
  2597. * DeltaDstIn - bytes from one Dst scan line to next *
  2598. * cy - number of scan lines *
  2599. * uF - Foreground color *
  2600. * uB - Background color *
  2601. * pS - pointer to destination SURFACE *
  2602. * *
  2603. * Return Value: *
  2604. * *
  2605. * None *
  2606. * *
  2607. \**************************************************************************/
  2608. VOID
  2609. vSrcTranCopyS4D32(
  2610. PBYTE pjSrcIn,
  2611. LONG SrcLeft,
  2612. LONG DeltaSrcIn,
  2613. PBYTE pjDstIn,
  2614. LONG DstLeft,
  2615. LONG DstRight,
  2616. LONG DeltaDstIn,
  2617. LONG cy,
  2618. ULONG uF,
  2619. ULONG uB,
  2620. SURFACE *pS
  2621. )
  2622. {
  2623. ULONG flRed, cRedRight, uRedF, flRedRight;
  2624. ULONG flGre, cGreRight, uGreF, flGreRight;
  2625. ULONG flBlu, cBluRight, uBluF, flBluRight;
  2626. ULONG uT, dT, u;
  2627. CONST ULONG *aul;
  2628. int cPreamble, cMiddle, cPostamble, A, B;
  2629. BYTE j;
  2630. XEPALOBJ xpo;
  2631. if(pS->pPal == NULL)
  2632. {
  2633. PDEVOBJ pdo(pS->hdev());
  2634. xpo.ppalSet(pdo.ppalSurf());
  2635. }
  2636. else
  2637. {
  2638. xpo.ppalSet(pS->pPal);
  2639. }
  2640. ASSERTGDI(xpo.bValid(), "Invalid XEPALOBJ" );
  2641. if (xpo.bIsBitfields())
  2642. {
  2643. flRed = xpo.flRed(); // masks red bits
  2644. cRedRight = xpo.cRedRight();
  2645. flGre = xpo.flGre(); // masks green bits
  2646. cGreRight = xpo.cGreRight();
  2647. flBlu = xpo.flBlu(); // masks blu bits
  2648. cBluRight = xpo.cBluRight();
  2649. }
  2650. else if (xpo.bIsRGB())
  2651. {
  2652. // assuming 8+8+8
  2653. flRed = 0x0000ff;
  2654. cRedRight = 0;
  2655. flGre = 0x00ff00;
  2656. cGreRight = 8;
  2657. flBlu = 0xff0000;
  2658. cBluRight = 16;
  2659. }
  2660. else if (xpo.bIsBGR())
  2661. {
  2662. // assuming 8+8+8
  2663. flRed = 0xff0000;
  2664. cRedRight = 16;
  2665. flGre = 0x00ff00;
  2666. cGreRight = 8;
  2667. flBlu = 0x0000ff;
  2668. cBluRight = 0;
  2669. }
  2670. else
  2671. {
  2672. RIP("unsuported palette format\n");
  2673. }
  2674. uRedF = (uF & flRed) >> cRedRight;
  2675. flRedRight = flRed >> cRedRight;
  2676. uGreF = (uF & flGre) >> cGreRight;
  2677. flGreRight = flGre >> cGreRight;
  2678. uBluF = (uF & flBlu) >> cBluRight;
  2679. flBluRight = flBlu >> cBluRight;
  2680. #if DBG
  2681. if (gflFontDebug & DEBUG_AA)
  2682. {
  2683. DbgPrint(
  2684. "vSrcTranCopyS4D32(\n"
  2685. " PBYTE pjSrcIn = %-#x\n"
  2686. " LONG SrcLeft = %d\n"
  2687. " LONG DeltaSrcIn = %d\n"
  2688. " PBYTE pjDstIn = %-#x\n"
  2689. " LONG DstLeft = %d\n"
  2690. " LONG DstRight = %d\n"
  2691. " LONG DeltaDstIn = %d\n"
  2692. " LONG cy = %d\n"
  2693. " ULONG uF = %-#x\n"
  2694. " ULONG uB = %-#x\n"
  2695. " SURFACE *pS = %-#x\n"
  2696. , pjSrcIn
  2697. , SrcLeft
  2698. , DeltaSrcIn
  2699. , pjDstIn
  2700. , DstLeft
  2701. , DstRight
  2702. , DeltaDstIn
  2703. , cy
  2704. , uF
  2705. , uB
  2706. , pS
  2707. );
  2708. DbgPrint(
  2709. " flRed = %-#x\n"
  2710. " cRedRight = %d\n"
  2711. " uRedF = %-#x\n"
  2712. " flRedRight = %-#x\n"
  2713. , flRed, cRedRight, uRedF, flRedRight
  2714. );
  2715. DbgPrint(
  2716. " flGre = %-#x\n"
  2717. " cGreRight = %d\n"
  2718. " uGreF = %-#x\n"
  2719. " flGreRight = %-#x\n"
  2720. , flGre, cGreRight, uGreF, flGreRight
  2721. );
  2722. DbgPrint(
  2723. " flBlu = %-#x\n"
  2724. " cBluRight = %d\n"
  2725. " uBluF = %-#x\n"
  2726. " flBluRight = %-#x\n"
  2727. , flBlu, cBluRight, uBluF, flBluRight
  2728. );
  2729. DbgBreakPoint();
  2730. }
  2731. #endif
  2732. /*****************************************************************************
  2733. * *
  2734. * The CCC macro blends forground and background colors of a single color *
  2735. * channel. Gamma correction is taken into account using an approximate *
  2736. * correction scheme. uB contains all three background colors. We first *
  2737. * mask off the bits of interest and then shift them down until the *
  2738. * least significant color bit resides at the lowest bit of the dword. *
  2739. * The answer is placed in uT ("temporary ULONG"). This must be done for *
  2740. * each pixel in the destination. The same thing has been done for the *
  2741. * each of the forground color channels and placed in uRedF, uGreF, *
  2742. * and uBluF. These values do not change from pixel to pixel and so the *
  2743. * calculation of these down shifted forground color channel values is *
  2744. * done up front before the loop. Then for each color channel we *
  2745. * calculate the difference between the down-shifted forground- and *
  2746. * background color channels and place the answer in dT ("temporary *
  2747. * difference"). The approximate gamma correction is done in the *
  2748. * following manner: If the background color value is smaller than *
  2749. * the foreground color value then the approximate correction is: *
  2750. * *
  2751. * (c_f >= c_b): *
  2752. * *
  2753. * c = c_b + alpha_k ^ (1/gamma) * (c_f - c_b) *
  2754. * *
  2755. * (c_f <= c_b): *
  2756. * *
  2757. * c = c_b + (1 - (1 - alpha_k)^(1/gamma)) * (c_f - c_b) *
  2758. * *
  2759. * where *
  2760. * *
  2761. * c := blended color *
  2762. * c_b := background color *
  2763. * c_f := foreground color *
  2764. * alpha_k := k'th blending fraction = k == 0 ? 0 : (k+1)/16; *
  2765. * gamma := 2.33 *
  2766. * *
  2767. * I have storred all sixteen values of alpha_k ^ (1/gamma) in 16.16 *
  2768. * representation in an array ULONG aulB[16] and I have storred the *
  2769. * values of 1 - (1 - alpha_k)^(1/gamma) in aulIB[k] *
  2770. * *
  2771. * Thus the blended color value is *
  2772. * *
  2773. * (c_f >= c_b): *
  2774. * *
  2775. * c = (2^16 * c_b + aulB[k] * (c_f - c_b)) / 2^16 *
  2776. * *
  2777. * *
  2778. * (c_f <= c_b): *
  2779. * *
  2780. * c = (2^16 * c_b + aulB[15-k] * (c_f - c_b)) / 2^16 *
  2781. * Instead of accessing aulB[15-k], I access aulIB which has *
  2782. * aulIB[k] = aulB[15-k] *
  2783. * In the macro below, I actually blend the down-shifted color *
  2784. * channel values and then shift the answer up and mask it (the *
  2785. * mask shouldn't be necessary, but this is a precaution). *
  2786. * *
  2787. *****************************************************************************/
  2788. #define CCC(Color,jj) \
  2789. uT = (uB & fl##Color) >> c##Color##Right; \
  2790. dT = u##Color##F - uT; \
  2791. aul = ((LONG) dT < 0) ? aulIB : aulB; \
  2792. u |= (((dT * aul[jj] + (uT << 16)) >> 16) << c##Color##Right) & fl##Color
  2793. /******************************************************************************
  2794. * *
  2795. * The SETCOLOR macro looks at the blending value. If it is zero then *
  2796. * the destination pixel does not change and we do nothing. If the blending *
  2797. * value is 15 then the destination pixel should take the forground color *
  2798. * , no blending is necessary. If the blending value is one of 1..14 then *
  2799. * all three color channels are blended and added together. *
  2800. * *
  2801. ******************************************************************************/
  2802. #define SETCOLOR(jj) \
  2803. if (j = (jj)) \
  2804. { \
  2805. if (j == 15) \
  2806. { \
  2807. u = uF; \
  2808. } \
  2809. else \
  2810. { \
  2811. u = 0; \
  2812. uB = *pulDst; \
  2813. CCC(Red,j); \
  2814. CCC(Gre,j); \
  2815. CCC(Blu,j); \
  2816. } \
  2817. *pulDst = u; \
  2818. } \
  2819. pulDst++
  2820. /************************************************************************
  2821. * *
  2822. * Each nyble of the source bitmap corresponds to 32 bits *
  2823. * in the destination bitmap. I have decided to arrange things *
  2824. * so that the inner most loop sets two pixels at a time. The *
  2825. * first of these two pixels starts on an even address in *
  2826. * the destination. After separating these 'aligned' pairs *
  2827. * in the middle of the scan there may be some left over *
  2828. * at the left (preamble) and the right (postamble). The *
  2829. * preamble can have at most one pixel in it. If there is *
  2830. * a pixel in the postamble then it correxponds to the *
  2831. * low nyble of the source byte. If there is a pixel in *
  2832. * the postamble then it corresponds to the high nyble of *
  2833. * the source byte. Each time, we have dealt with an odd *
  2834. * x-coordinate in the destination (corresponding to the *
  2835. * low nyble in the source byte) we advance the source pointer *
  2836. * to the next byte. *
  2837. * *
  2838. ************************************************************************/
  2839. A = (DstLeft + 1) & ~1; // nearest multiple of 2 left of left edge
  2840. B = (DstRight ) & ~1; // nearest multiple of 2 right of right edge
  2841. cPreamble = A - DstLeft; // # pixels in preamble
  2842. cMiddle = (B - A)/2; // # pixels in middle
  2843. cPostamble = DstRight - B; // # pixels in postamble
  2844. pjSrcIn += SrcLeft / 2; // points to first source byte
  2845. pjDstIn += DstLeft * sizeof(ULONG); // points to first dst DWORD
  2846. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  2847. {
  2848. int i;
  2849. BYTE jSrc;
  2850. BYTE *pjSrc = pjSrcIn;
  2851. ULONG *pulDst = (ULONG*) pjDstIn;
  2852. if (cPreamble)
  2853. {
  2854. SETCOLOR(*pjSrc & 15);
  2855. pjSrc++;
  2856. }
  2857. for (i = 0; i < cMiddle; i++)
  2858. {
  2859. jSrc = *pjSrc;
  2860. SETCOLOR(jSrc >> 4);
  2861. SETCOLOR(jSrc & 15);
  2862. pjSrc++;
  2863. }
  2864. if (cPostamble)
  2865. {
  2866. SETCOLOR(*pjSrc >> 4);
  2867. }
  2868. }
  2869. #undef SETCOLOR
  2870. #undef CCC
  2871. }
  2872. /******************************Public*Routine******************************\
  2873. * *
  2874. * Routine Name: *
  2875. * *
  2876. * vOrNonAlignedGrayGlyphEven *
  2877. * *
  2878. * Routine Description: *
  2879. * *
  2880. * Writes the a single gray glyph to a 4bpp buffer. This is for the *
  2881. * special case where the destination starts on a non byte (nyble ) *
  2882. * boundary and the glyph images is an even number of pixels wide. *
  2883. * *
  2884. * The source gray pixel image is guaranteed to have its initial scan *
  2885. * start on a 32-bit boundary, all subsequent scans start on byte *
  2886. * boundaries. *
  2887. * *
  2888. * Arguments: *
  2889. * *
  2890. * pgb - address of gray GLYPHBITS structure *
  2891. * dpSrcScan - number of bytes between address of start of glyph scans *
  2892. * pjDstScan - starting address of glyph image in destination buffer *
  2893. * dpDstScan - increment between scan addresses in destination buffer *
  2894. * *
  2895. * Return Value: *
  2896. * *
  2897. * None *
  2898. * *
  2899. \**************************************************************************/
  2900. void
  2901. vOrNonAlignedGrayGlyphEven(
  2902. GLYPHBITS* pgb ,
  2903. unsigned dpSrcScan,
  2904. BYTE* pjDstScan,
  2905. unsigned dpDstScan
  2906. )
  2907. {
  2908. /*
  2909. 0 1 2 3 4 <-- byte number
  2910. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2911. |n n |n n |n n |n n |n n | | | |
  2912. | 1 0| 3 2| 5 4| 7 6| 9 8| | | |
  2913. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2914. ^ ^ ^
  2915. pjSrc Hi Lo
  2916. 0 1 2 3 4 5 <-- byte number
  2917. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2918. | n |n n |n n |n n |n n |n | | |
  2919. | 1| 0 3| 2 5| 4 7| 6 9| 8 | | |
  2920. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2921. ^ ^
  2922. pjDst pjDstLast
  2923. */
  2924. #if DBG
  2925. if (gflFontDebug & DEBUG_AA)
  2926. {
  2927. DbgPrint(
  2928. "void\n"
  2929. "vOrNonAlignedGrayGlyphEven(\n"
  2930. " GLYPHBITS* pgb = %-#x\n"
  2931. " unsigned dpSrcScan = %-#x\n"
  2932. " BYTE* pjDstScan = %-#x\n"
  2933. " unsigned dpDstScan = %-#x\n"
  2934. " )\n"
  2935. , pgb
  2936. , dpSrcScan
  2937. , pjDstScan
  2938. , dpDstScan
  2939. );
  2940. DbgBreakPoint();
  2941. }
  2942. #endif
  2943. BYTE jLo, jHi, *pjSrc, *pjDst, *pjSrcOut, *pjDstScanOut;
  2944. dpSrcScan = (pgb->sizlBitmap.cx + 1)/2;
  2945. pjSrcOut = pgb->aj;
  2946. pjDstScanOut = pjDstScan + ((unsigned) pgb->sizlBitmap.cy) * dpDstScan;
  2947. for ( ; pjDstScan < pjDstScanOut ; pjDstScan += dpDstScan)
  2948. {
  2949. pjSrc = pjSrcOut;
  2950. pjSrcOut += dpSrcScan;
  2951. for (jLo = 0, pjDst = pjDstScan; pjSrc < pjSrcOut; )
  2952. {
  2953. jHi = *pjSrc++;
  2954. *pjDst++ |= (jLo << 4) + (jHi >> 4);
  2955. jLo = jHi;
  2956. }
  2957. *pjDst |= (jLo << 4);
  2958. }
  2959. }
  2960. /******************************Public*Routine******************************\
  2961. * *
  2962. * Routine Name: *
  2963. * *
  2964. * vOrNonAlignedGrayGlyphOdd *
  2965. * *
  2966. * Routine Description: *
  2967. * *
  2968. * Writes the a single gray glyph to a 4bpp buffer. This is for the *
  2969. * special case where the destination starts on a non byte (nyble ) *
  2970. * boundary and the glyph images is an odd number of pixels wide. *
  2971. * *
  2972. * The source gray pixel image is guaranteed to have its initial scan *
  2973. * start on a 32-bit boundary, all subsequent scans start on byte *
  2974. * boundaries. *
  2975. * *
  2976. * Arguments: *
  2977. * *
  2978. * pgb - address of gray GLYPHBITS structure *
  2979. * dpSrcScan - number of bytes between address of start of glyph scans *
  2980. * pjDstScan - starting address of glyph image in destination buffer *
  2981. * dpDstScan - increment between scan addresses in destination buffer *
  2982. * *
  2983. * Return Value: *
  2984. * *
  2985. * None *
  2986. * *
  2987. \**************************************************************************/
  2988. void
  2989. vOrNonAlignedGrayGlyphOdd(
  2990. GLYPHBITS* pgb ,
  2991. unsigned dpSrcScan,
  2992. BYTE* pjDstScan,
  2993. unsigned dpDstScan
  2994. )
  2995. {
  2996. /*
  2997. 0 1 2 3 4 <-- byte number
  2998. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2999. |n n |n n |n n |n n |n | | | |
  3000. | 1 0| 3 2| 5 4| 7 6| 9 | | | |
  3001. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3002. ^ ^ ^
  3003. pjSrc Hi Lo
  3004. 0 1 2 3 4 5 <-- byte number
  3005. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3006. | n |n n |n n |n n |n n | | | |
  3007. | 1| 0 3| 2 5| 4 7| 6 9| | | |
  3008. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3009. ^ ^
  3010. pjDst pjDstLast
  3011. */
  3012. BYTE j1, j0, *pjDst, *pjSrc, *pjDstLast, *pjDstScanOut;
  3013. unsigned cy = (unsigned) pgb->sizlBitmap.cy;
  3014. unsigned cx = (unsigned) pgb->sizlBitmap.cx / 2;
  3015. BYTE *pjSrcScan = &(pgb->aj[0]);
  3016. #if DBG
  3017. if (gflFontDebug & DEBUG_AA)
  3018. {
  3019. DbgPrint(
  3020. "void\n"
  3021. "vOrNonAlignedGrayGlyphOdd(\n"
  3022. " GLYPHBITS* pgb = %-#x\n"
  3023. " unsigned dpSrcScan = %-#x\n"
  3024. " BYTE* pjDstScan = %-#x\n"
  3025. " unsigned dpDstScan = %-#x\n"
  3026. " )\n"
  3027. , pgb
  3028. , dpSrcScan
  3029. , pjDstScan
  3030. , dpDstScan
  3031. );
  3032. DbgBreakPoint();
  3033. }
  3034. #endif
  3035. for (
  3036. pjDstScanOut = pjDstScan + cy * dpDstScan
  3037. ; pjDstScan < pjDstScanOut
  3038. ; pjDstScan += dpDstScan, pjSrcScan += dpSrcScan
  3039. )
  3040. {
  3041. //
  3042. // set the source and destination pointers to point to the
  3043. // start of the scans
  3044. //
  3045. pjSrc = pjSrcScan;
  3046. pjDst = pjDstScan;
  3047. //
  3048. // do the first pixel in the scan
  3049. //
  3050. j1 = *pjSrc;
  3051. *pjDst |= (j1 >> 4) & 0x0f;
  3052. //
  3053. // advance the pointers to the next pixel in the scans
  3054. //
  3055. pjSrc++;
  3056. pjDst++;
  3057. //
  3058. // do the rest of the pixels in the scan
  3059. //
  3060. for (
  3061. pjDstLast = pjDst + cx
  3062. ; pjDst < pjDstLast
  3063. ; pjDst++, pjSrc++
  3064. )
  3065. {
  3066. j0 = j1;
  3067. j1 = *pjSrc;
  3068. *pjDst |= ((j1 >> 4) & 0x0f) | ((j0 << 4) & 0xf0);
  3069. }
  3070. //
  3071. // last pixel in the scan has already been done
  3072. //
  3073. }
  3074. }
  3075. /******************************Public*Routine******************************\
  3076. * *
  3077. * Routine Name: *
  3078. * *
  3079. * vOrAlignedGrayGlyphEven *
  3080. * *
  3081. * Routine Description: *
  3082. * *
  3083. * Writes the a single gray glyph to a 4bpp buffer. This is for the *
  3084. * special case where the destination starts on a byte aligned boundary *
  3085. * and the glyph is an even number of pixels wide. *
  3086. * *
  3087. * This routine can be used for glyphs with odd widths. *
  3088. * *
  3089. * The source gray pixel image is guaranteed to have its initial scan *
  3090. * start on a 32-bit boundary, all subsequent scans start on byte *
  3091. * boundaries. *
  3092. * *
  3093. * Arguments: *
  3094. * *
  3095. * pgb - address of gray GLYPHBITS structure *
  3096. * dpSrcScan - number of bytes between address of start of glyph scans *
  3097. * pjDstScan - starting address of glyph image in destination buffer *
  3098. * dpDstScan - increment between scan addresses in destination buffer *
  3099. * *
  3100. * Return Value: *
  3101. * *
  3102. * None *
  3103. * *
  3104. \**************************************************************************/
  3105. void
  3106. vOrAlignedGrayGlyphEven(
  3107. GLYPHBITS* pgb ,
  3108. unsigned dpSrcScan,
  3109. BYTE* pjDstScan,
  3110. unsigned dpDstScan
  3111. )
  3112. {
  3113. /*
  3114. 0 1 2 3 4 <-- byte number
  3115. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3116. |n n |n n |n n |n n |n n | | | |
  3117. | 1 0| 3 2| 5 4| 7 6| 9 8| | | |
  3118. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3119. ^ ^ ^
  3120. pjSrc Hi Lo
  3121. 0 1 2 3 4 <-- byte number
  3122. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3123. |n n |n n |n n |n n |n n | | | |
  3124. | 1 0| 3 2| 5 4| 7 6| 9 8| | | |
  3125. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  3126. ^ ^
  3127. pjDst pjDstOut
  3128. Note that this routine will also work for source
  3129. glyphs with an odd number of pixels because
  3130. the source glyph is padded with zeros. This means
  3131. that for the case of odd length scans the last
  3132. byte is or'ed into the destination but the
  3133. extra nyble of the source is guaranteed to have
  3134. the value zero and thus has no effect.
  3135. */
  3136. BYTE *pjDst, *pjSrc, *pjDstOut, *pjDstScanOut;
  3137. unsigned cy = (unsigned) pgb->sizlBitmap.cy;
  3138. // I round cx up to the nearest byte. This makes no
  3139. // difference for glyphs of even width but it will
  3140. // get that last column for glyphs with odd width.
  3141. unsigned cx = (unsigned) (pgb->sizlBitmap.cx+1) / 2;
  3142. BYTE *pjSrcScan = &(pgb->aj[0]);
  3143. #if DBG
  3144. if (gflFontDebug & DEBUG_AA)
  3145. {
  3146. DbgPrint(
  3147. "void\n"
  3148. "vOrAlignedGrayGlyphEven(\n"
  3149. " GLYPHBITS* pgb = %-#x\n"
  3150. " unsigned dpSrcScan = %-#x\n"
  3151. " BYTE* pjDstScan = %-#x\n"
  3152. " unsigned dpDstScan = %-#x\n"
  3153. " )\n"
  3154. , pgb
  3155. , dpSrcScan
  3156. , pjDstScan
  3157. , dpDstScan
  3158. );
  3159. DbgBreakPoint();
  3160. }
  3161. #endif
  3162. for (
  3163. pjDstScanOut = pjDstScan + cy * dpDstScan
  3164. ; pjDstScan < pjDstScanOut
  3165. ; pjDstScan += dpDstScan, pjSrcScan += dpSrcScan
  3166. )
  3167. {
  3168. pjSrc = pjSrcScan;
  3169. pjDst = pjDstScan;
  3170. for (pjDstOut = pjDst + cx ; pjDst < pjDstOut; pjDst++, pjSrc++)
  3171. {
  3172. *pjDst |= *pjSrc;
  3173. }
  3174. }
  3175. }
  3176. void (*(apfnGray[4]))(GLYPHBITS*, unsigned, BYTE*, unsigned) =
  3177. {
  3178. vOrAlignedGrayGlyphEven
  3179. , vOrAlignedGrayGlyphEven // can handle odd width glyphs
  3180. , vOrNonAlignedGrayGlyphEven
  3181. , vOrNonAlignedGrayGlyphOdd
  3182. };
  3183. /******************************Public*Routine******************************\
  3184. * *
  3185. * Routine Name: *
  3186. * *
  3187. * draw_gray_nf_ntb_o_to_temp_start *
  3188. * *
  3189. * Routine Description: *
  3190. * *
  3191. * Assembles a gray glyph string into a temporary 4bpp right and left *
  3192. * DWORD aligned buffer. This routine assumes a variable pitch font. *
  3193. * *
  3194. * Arguments: *
  3195. * *
  3196. * pGlyphPos - pointer to an array of cGlyph gray GLYPHPOS structures *
  3197. * cGlyphs - count of gray glyphs in array starting at pGlyphPos *
  3198. * pjDst - pointer to a 4bpp buffer where string is to be assembled *
  3199. * This buffer is DWORD aligned at the left and right *
  3200. * edges of each scan. *
  3201. * ulLeftEdge - screen coordinate corresponding to the left edge of *
  3202. * the temporary buffer *
  3203. * dpDst - count of bytes in each scan of the destination buffer *
  3204. * (this must be a multiple of 4 because the buffer is *
  3205. * DWORD aligned on each scan). *
  3206. * ulCharInc - This must be zero. *
  3207. * ulTempTop - screen coordinate corresponding to the top of the *
  3208. * destination buffer. This is used to convert the *
  3209. * glyph positions on the screen to addresses in the *
  3210. * destination bitmap. *
  3211. * *
  3212. * Return Value: *
  3213. * *
  3214. * None *
  3215. * *
  3216. \**************************************************************************/
  3217. extern "C" VOID draw_gray_nf_ntb_o_to_temp_start(
  3218. PGLYPHPOS pGlyphPos,
  3219. ULONG cGlyphs,
  3220. PUCHAR pjDst,
  3221. ULONG ulLeftEdge,
  3222. ULONG dpDst,
  3223. ULONG ulCharInc,
  3224. ULONG ulTempTop
  3225. )
  3226. {
  3227. GLYPHBITS *pgb; // pointer to current GLYPHBITS
  3228. int x; // pixel offset of the
  3229. // left edge of the glyph bitmap
  3230. // from the left edge of the
  3231. // output (4-bpp) bitmap
  3232. int y; // the pixel offset of the top edge
  3233. // of the glyph bitmap from the top
  3234. // edge of the output bitmap.
  3235. unsigned bOddPos; // (x-coordinate is odd) ? 1 : 0
  3236. unsigned cx; // number of pixels per glyph scan
  3237. // If non zero then the destination
  3238. // bitmap is out of alignment with
  3239. // the source glyph by a one nyble
  3240. // shift and a single byte of the
  3241. // source will affect two consecutive
  3242. // bytes of the destination.
  3243. unsigned dpSrc; // number of bytes per source scan. Each
  3244. // scan is BYTE aligned.
  3245. // = ceil(4*cx/8) = floor((cx+1)/2)
  3246. GLYPHPOS *pgpOut; // sentinel for loop
  3247. BYTE *pj; // pointer into Buffer corresponding
  3248. // to the upper left pixel of the
  3249. // current gray glyph
  3250. pj = pjDst;
  3251. for (pgpOut = pGlyphPos + cGlyphs; pGlyphPos < pgpOut; pGlyphPos++)
  3252. {
  3253. pgb = pGlyphPos->pgdf->pgb;
  3254. x = pGlyphPos->ptl.x + pgb->ptlOrigin.x - ulLeftEdge;
  3255. y = pGlyphPos->ptl.y + pgb->ptlOrigin.y - ulTempTop ;
  3256. bOddPos = (unsigned) x & 1;
  3257. cx = (unsigned) pgb->sizlBitmap.cx;
  3258. dpSrc = (cx + 1)/2;
  3259. pj = pjDst + (y * dpDst) + (x/2);
  3260. (*(apfnGray[(cx & 1) + 2*bOddPos]))(pgb, dpSrc, pj, dpDst);
  3261. }
  3262. }
  3263. /******************************Public*Routine******************************\
  3264. * *
  3265. * Routine Name: *
  3266. * *
  3267. * draw_gray_f_ntb_o_to_temp_start *
  3268. * *
  3269. * Routine Description: *
  3270. * *
  3271. * Assembles a gray glyph string into a temporary 4bpp right and left *
  3272. * DWORD aligned buffer. This routine assumes a fixed pitch font with *
  3273. * character increment equal to ulCharInc *
  3274. * *
  3275. * Arguments: *
  3276. * *
  3277. * pGlyphPos - pointer to an array of cGlyph gray GLYPHPOS structures *
  3278. * cGlyphs - count of gray glyphs in array starting at pGlyphPos *
  3279. * pjDst - pointer to a 4bpp buffer where string is to be assembled *
  3280. * This buffer is DWORD aligned at the left and right *
  3281. * edges of each scan. *
  3282. * ulLeftEdge - screen coordinate corresponding to the left edge of *
  3283. * the temporary buffer *
  3284. * dpDst - count of bytes in each scan of the destination buffer *
  3285. * (this must be a multiple of 4 because the buffer is *
  3286. * DWORD aligned on each scan). *
  3287. * ulCharInc - This must be zero. *
  3288. * ulTempTop - screen coordinate corresponding to the top of the *
  3289. * destination buffer. This is used to convert the *
  3290. * glyph positions on the screen to addresses in the *
  3291. * destination bitmap. *
  3292. * *
  3293. * Return Value: *
  3294. * *
  3295. * None *
  3296. * *
  3297. \**************************************************************************/
  3298. extern "C" VOID draw_gray_f_ntb_o_to_temp_start(
  3299. PGLYPHPOS pGlyphPos,
  3300. ULONG cGlyphs,
  3301. PUCHAR pjDst,
  3302. ULONG ulLeftEdge,
  3303. ULONG dpDst,
  3304. ULONG ulCharInc,
  3305. ULONG ulTempTop
  3306. )
  3307. {
  3308. GLYPHBITS *pgb; // pointer to current GLYPHBITS
  3309. int x; // x-coordinate of the current
  3310. // character origin with respect
  3311. // to the upper left pixel of the
  3312. // output (4-bpp) bitmap
  3313. int y; // y-coordinate of the current
  3314. // character origin with respect
  3315. // to the upper left pixel of the
  3316. // output (4-bpp) bitmap
  3317. unsigned bOddPos; // (x-coordinate is odd) ? 1 : 0
  3318. unsigned cx; // number of pixels per glyph scan
  3319. // If non zero then the destination
  3320. // bitmap is out of alignment with
  3321. // the source glyph by a one nyble
  3322. // shift and a single byte of the
  3323. // source will affect two consecutive
  3324. // bytes of the destination.
  3325. unsigned dpSrc; // number of bytes per source scan. Each
  3326. // scan is BYTE aligned.
  3327. // = ceil(4*cx/8) = floor((cx+1)/2)
  3328. GLYPHPOS *pgpOut; // sentinel for loop
  3329. BYTE *pj; // pointer into Buffer corresponding
  3330. // to the upper left pixel of the
  3331. // current gray glyph
  3332. #if DBG
  3333. if (gflFontDebug & DEBUG_AA)
  3334. {
  3335. DbgPrint(
  3336. "draw_gray_f_ntb_o_to_temp_start(\n"
  3337. " PGLYPHPOS pGlyphPos = %-#x\n"
  3338. " ULONG cGlyphs = %u\n"
  3339. " PUCHAR pjDst = %-#x\n"
  3340. " ULONG ulLeftEdge = %u\n"
  3341. " ULONG dpDst = %u\n"
  3342. " ULONG ulCharInc = %u\n"
  3343. " ULONG ulTempTop = %u\n"
  3344. " )\n"
  3345. , pGlyphPos
  3346. , cGlyphs
  3347. , pjDst
  3348. , ulLeftEdge
  3349. , dpDst
  3350. , ulCharInc
  3351. , ulTempTop
  3352. );
  3353. DbgBreakPoint();
  3354. }
  3355. #endif
  3356. // (x,y) = position of first CHARACTER ORIGIN with respect to
  3357. // the upper left pixel of the destination 4bpp bitmap
  3358. x = pGlyphPos->ptl.x - ulLeftEdge;
  3359. y = pGlyphPos->ptl.y - ulTempTop;
  3360. for (pgpOut = pGlyphPos + cGlyphs; pGlyphPos < pgpOut; x += ulCharInc, pGlyphPos++)
  3361. {
  3362. int xT, yT; // position of UPPER LEFT pixel of glyph
  3363. // with respect to the upper left pixel
  3364. // of the bitmap.
  3365. pgb = pGlyphPos->pgdf->pgb;
  3366. xT = x + pgb->ptlOrigin.x;
  3367. yT = y + pgb->ptlOrigin.y;
  3368. bOddPos = (unsigned) xT & 1;
  3369. cx = (unsigned) pgb->sizlBitmap.cx;
  3370. dpSrc = (cx + 1)/2;
  3371. pj = pjDst + (yT * dpDst) + (xT/2);
  3372. #if DBG
  3373. if (gflFontDebug & DEBUG_AA)
  3374. {
  3375. DbgPrint(
  3376. "\n"
  3377. " pgb = %-#x\n"
  3378. " ptlOrigin = (%d,%d)\n"
  3379. " xT = %d\n"
  3380. " yT = %d\n"
  3381. " bOddPos = %d\n"
  3382. , pgb
  3383. , pgb->ptlOrigin.x
  3384. , pgb->ptlOrigin.y
  3385. , xT
  3386. , yT
  3387. , bOddPos
  3388. );
  3389. DbgPrint(
  3390. " cx = %u\n"
  3391. " dpSrc = %u\n"
  3392. " pj = %-#x\n"
  3393. " (cx & 1) + 2*bOddPos = %d\n"
  3394. , cx
  3395. , dpSrc
  3396. , pj
  3397. , (cx & 1) + 2*bOddPos
  3398. );
  3399. DbgBreakPoint();
  3400. }
  3401. #endif
  3402. (*(apfnGray[(cx & 1) + 2*bOddPos]))(pgb, dpSrc, pj, dpDst);
  3403. }
  3404. }
  3405. #if DBG
  3406. /******************************Public*Routine******************************\
  3407. * *
  3408. * Routine Name: *
  3409. * *
  3410. * vDumpGrayBuffer *
  3411. * *
  3412. * Routine Description: *
  3413. * *
  3414. * Debug routine for dumping the temporary 4bpp gray string buffer *
  3415. * *
  3416. * Arguments: *
  3417. * *
  3418. * pjBuffer - pointer to gray 4bpp image *
  3419. * dpjScan - count of bytes per scan *
  3420. * prcl - rectangle surrounding 4bpp gray image *
  3421. * *
  3422. * Return Value: *
  3423. * *
  3424. * None *
  3425. * *
  3426. \**************************************************************************/
  3427. void vDumpGrayBuffer(BYTE *pjBuffer, ULONG dpjScan, RECTL *prcl)
  3428. {
  3429. BYTE *pj, *pjNext, *pjOut;
  3430. static char achNyble[16] = {
  3431. ' ','1','2','3','4','5','6','7'
  3432. ,'8','9','a','b','c','d','e','f'
  3433. };
  3434. DbgPrint(
  3435. "vDumpGrayBuffer(\n"
  3436. " pjBuffer = %-#x\n"
  3437. " dpjScan = %u\n"
  3438. " prcl = %-#x ==> %d %d %d %d\n"
  3439. ")\n"
  3440. , pjBuffer
  3441. , dpjScan
  3442. , prcl
  3443. , prcl->left, prcl->top, prcl->right, prcl->bottom
  3444. );
  3445. DbgPrint("+");
  3446. for (ULONG i = 0; i < dpjScan; i++)
  3447. DbgPrint("--");
  3448. DbgPrint("+\n");
  3449. pjOut = pjBuffer + dpjScan * (prcl->bottom - prcl->top);
  3450. for (pj = pjBuffer; pj < pjOut;) {
  3451. DbgPrint("|");
  3452. for (pjNext = pj + dpjScan; pj < pjNext; pj++)
  3453. DbgPrint("%c%c", achNyble[*pj >> 4], achNyble[*pj & 15]);
  3454. DbgPrint("|\n");
  3455. }
  3456. DbgPrint("+");
  3457. for (i = 0; i < dpjScan; i++)
  3458. DbgPrint("--");
  3459. DbgPrint("+\n");
  3460. }
  3461. /******************************Public*Routine******************************\
  3462. * *
  3463. * Routine Name: *
  3464. * *
  3465. * vPrintGrayGLYPHBITS *
  3466. * *
  3467. * Routine Description: *
  3468. * *
  3469. * Dumps Gray GLYPHBITS to the debug screen *
  3470. * *
  3471. * Arguments: *
  3472. * *
  3473. * pgb - pointer to a gray GLYPHBITS structure *
  3474. * *
  3475. * Return Value: *
  3476. * *
  3477. * none *
  3478. * *
  3479. \**************************************************************************/
  3480. void vPrintGrayGLYPHBITS(GLYPHBITS *pgb)
  3481. {
  3482. BYTE *pj, *pjNext, *pjEnd;
  3483. ptrdiff_t cjScan, i;
  3484. static char achNyble[16] =
  3485. {' ','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
  3486. DbgPrint(
  3487. "Gray GLYPHBITS at = %-#x\n"
  3488. " ptlOrigin = %d %d\n"
  3489. " sizlBitmap = %u %u\n"
  3490. , pgb
  3491. , pgb->ptlOrigin.x
  3492. , pgb->ptlOrigin.y
  3493. , pgb->sizlBitmap.cx
  3494. , pgb->sizlBitmap.cy
  3495. );
  3496. pj = pgb->aj;
  3497. cjScan = ((ptrdiff_t) pgb->sizlBitmap.cx + 1)/2;
  3498. pjNext = pj + cjScan;
  3499. pjEnd = pj + cjScan * (ptrdiff_t) pgb->sizlBitmap.cy;
  3500. DbgPrint("+");
  3501. for (i = 0; i < cjScan; i++)
  3502. DbgPrint("--");
  3503. DbgPrint("+\n");
  3504. while (pj < pjEnd) {
  3505. DbgPrint("|");
  3506. while (pj < pjNext) {
  3507. DbgPrint("%c%c" , achNyble[*pj >> 4], achNyble[*pj & 0xf]);
  3508. pj += 1;
  3509. }
  3510. pj = pjNext;
  3511. pjNext += cjScan;
  3512. DbgPrint("|\n");
  3513. }
  3514. DbgPrint("+");
  3515. for (i = 0; i < cjScan; i++)
  3516. DbgPrint("--");
  3517. DbgPrint("+\n\n");
  3518. }
  3519. /******************************Public*Routine******************************\
  3520. * *
  3521. * Routine Name: *
  3522. * *
  3523. * vPrintGrayGLYPHPOS *
  3524. * *
  3525. * Routine Description: *
  3526. * *
  3527. * Dumps the contents of a Gray GLYPHPOS structure to the *
  3528. * debugger. *
  3529. * *
  3530. * Arguments: *
  3531. * *
  3532. * pgpos - a pointer to a gray GLYPHPOS structure *
  3533. * *
  3534. * Return Value: *
  3535. * *
  3536. * none *
  3537. * *
  3538. \**************************************************************************/
  3539. void vPrintGrayGLYPHPOS(GLYPHPOS *pgpos)
  3540. {
  3541. DbgPrint("Gray GLYPHPOS at %-#x\n", pgpos);
  3542. DbgPrint(" hg = %-#x\n", pgpos->hg);
  3543. DbgPrint(" pgdf = %-#x\n", pgpos->pgdf);
  3544. DbgPrint(" ptl = (%d,%d)\n", pgpos->ptl.x, pgpos->ptl.y);
  3545. // vPrintGrayGLYPHBITS(pgpos->pgdf->pgb);
  3546. }
  3547. /******************************Public*Routine******************************\
  3548. * *
  3549. * Routine Name: *
  3550. * *
  3551. * vDump8bppDIB *
  3552. * *
  3553. * Routine Description: *
  3554. * *
  3555. * Dumps an 8bpp DIB to the screen. This routine only recognizes the *
  3556. * four canonical shades of gray, all other colors are marked with *
  3557. * a question mark *
  3558. * *
  3559. * Arguments: *
  3560. * *
  3561. * SURFMEM reference. *
  3562. * *
  3563. * Return Value: *
  3564. * *
  3565. * none *
  3566. * *
  3567. \**************************************************************************/
  3568. void vDump8bppDIB(SURFMEM& surfmem)
  3569. {
  3570. char ch;
  3571. int j;
  3572. BYTE *pjScan, *pj, *pjOut;
  3573. ULONG dpjScan;
  3574. SURFOBJ *pso = surfmem.pSurfobj();
  3575. DbgPrint("Dumping the contents of the 8bpp DIB\n");
  3576. pso = surfmem.pSurfobj();
  3577. pjScan = (BYTE*) pso->pvBits;
  3578. dpjScan = 4 * ((pso->sizlBitmap.cx + 3) / 4);
  3579. DbgPrint("+");
  3580. for (j = 0; j < pso->sizlBitmap.cx; j++)
  3581. {
  3582. DbgPrint("-");
  3583. }
  3584. DbgPrint("+\n");
  3585. for (j = pso->sizlBitmap.cy; j; j--)
  3586. {
  3587. pj = pjScan;
  3588. pjOut = pjScan + pso->sizlBitmap.cx;
  3589. pjScan += dpjScan;
  3590. DbgPrint("|");
  3591. while (pj < pjOut)
  3592. {
  3593. switch (*pj++)
  3594. {
  3595. case 0: ch = ' '; break;
  3596. case 248: ch = '+'; break;
  3597. case 7: ch = '*'; break;
  3598. case 255: ch = '#'; break;
  3599. default: ch = '?'; break;
  3600. }
  3601. DbgPrint("%c",ch);
  3602. }
  3603. DbgPrint("|\n");
  3604. }
  3605. DbgPrint("+");
  3606. for (j = 0; j < pso->sizlBitmap.cx; j++)
  3607. {
  3608. DbgPrint("-");
  3609. }
  3610. DbgPrint("+\n");
  3611. }
  3612. #endif
  3613. // make them global for now, easier to debug
  3614. ULONG aulCacheCT[CT_LOOKUP];
  3615. HANDLE hCacheCT;
  3616. ULONG uFCacheCT;
  3617. ULONG uBCacheCT;
  3618. ULONG sizeCacheCT;
  3619. ULONG uGammaCacheCT;
  3620. VOID vGetBlendInfo (
  3621. ULONG size, SURFACE *pS, // input
  3622. ULONG uF, // foreground color
  3623. BLENDINFO *pbi // output
  3624. );
  3625. VOID *pvFillOpaqTableCT(
  3626. ULONG size,
  3627. ULONG uF,
  3628. ULONG uB,
  3629. SURFACE *pS,
  3630. BLENDINFO *pbi, // must NOT be NULL
  3631. BOOL bTransparent // in transparent case we must compute bi info,
  3632. ); // in opaque case do not need to
  3633. // if the table is up to date
  3634. VOID vClearTypeLookupTableLoop(
  3635. ULONG size,
  3636. SURFACE *pS,
  3637. BLENDINFO *pbi,
  3638. ULONG uF,
  3639. ULONG uB
  3640. )
  3641. {
  3642. // this can not fail, store the new info
  3643. sizeCacheCT = size;
  3644. uFCacheCT = uF;
  3645. uBCacheCT = uB;
  3646. uGammaCacheCT = gulGamma;
  3647. hCacheCT = pS->hGet();
  3648. ULONG *pul = aulCacheCT;
  3649. USHORT *pus = (USHORT*) aulCacheCT;
  3650. ULONG ul;
  3651. LONG dRedB, dGreB, dBluB; // precompute the diffs outside of the loop
  3652. LONG lRedB, lGreB, lBluB; // precompute outside of the loop
  3653. lRedB = pbi->pjGamma[((((uB & pbi->flRed) << pbi->iRedL) >> pbi->iRedR) & 255)];
  3654. lGreB = pbi->pjGamma[((((uB & pbi->flGre) << pbi->iGreL) >> pbi->iGreR) & 255)];
  3655. lBluB = pbi->pjGamma[((((uB & pbi->flBlu) << pbi->iBluL) >> pbi->iBluR) & 255)];
  3656. dRedB = pbi->lRedF - lRedB;
  3657. dGreB = pbi->lGreF - lGreB;
  3658. dBluB = pbi->lBluF - lBluB;
  3659. // the first and last entries are set outside the loop, for perf reasons
  3660. ULONG iTable;
  3661. const F_RGB *pfrgb;
  3662. for
  3663. (
  3664. iTable = 1, pfrgb = &gaOutTable[1];
  3665. iTable < (CT_LOOKUP-1);
  3666. iTable++, pfrgb++
  3667. )
  3668. {
  3669. ULONG ulRT, ulGT, ulBT;
  3670. ulRT = BLENDCT(pfrgb->kR, pbi->lRedF, lRedB, dRedB);
  3671. ulGT = BLENDCT(pfrgb->kG, pbi->lGreF, lGreB, dGreB);
  3672. ulBT = BLENDCT(pfrgb->kB, pbi->lBluF, lBluB, dBluB);
  3673. ASSERTGDI(((ulRT | ulGT | ulBT) & 0xffffff00) == 0,
  3674. "lookup table computation!!!\n");
  3675. ulRT = pbi->pjGammaInv[ulRT];
  3676. ulGT = pbi->pjGammaInv[ulGT];
  3677. ulBT = pbi->pjGammaInv[ulBT];
  3678. ul = (((ulRT << pbi->iRedR) >> pbi->iRedL) & pbi->flRed);
  3679. ul |= (((ulGT << pbi->iGreR) >> pbi->iGreL) & pbi->flGre);
  3680. ul |= (((ulBT << pbi->iBluR) >> pbi->iBluL) & pbi->flBlu);
  3681. if (size == sizeof(USHORT))
  3682. pus[iTable] = (USHORT)ul;
  3683. else
  3684. pul[iTable] = ul;
  3685. }
  3686. // make sure that blending and gamma correcting did not mess up
  3687. // backgroung and foreground pixels. (not sure that the round trip
  3688. // is guarranteed)
  3689. if (size == sizeof(USHORT))
  3690. {
  3691. pus[0] = (USHORT)uB; // set the first value to background:
  3692. pus[CT_LOOKUP-1] = (USHORT)uF; // set the last value to foreground
  3693. }
  3694. else
  3695. {
  3696. pul[0] = uB; // set the first value to background:
  3697. pul[CT_LOOKUP-1] = uF; // set the last value to foreground
  3698. }
  3699. }
  3700. /******************************Public*Routine******************************\
  3701. * *
  3702. * Routine Name *
  3703. * *
  3704. * vSrcOpaqCopyS8D16 *
  3705. * *
  3706. * Routine Description: *
  3707. * *
  3708. * Arguments: *
  3709. * *
  3710. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  3711. * SrcLeft - left (starting) pixel in src rectangle *
  3712. * DeltaSrcIn - bytes from one src scan line to next *
  3713. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  3714. * DstLeft - left(first) dst pixel *
  3715. * DstRight - right(last) dst pixel *
  3716. * DeltaDstIn - bytes from one Dst scan line to next *
  3717. * cy - number of scan lines *
  3718. * uF - Foreground color *
  3719. * uB - Background color *
  3720. * pS - pointer to destination SURFACE *
  3721. * *
  3722. * Return Value: *
  3723. * *
  3724. * None *
  3725. * *
  3726. \**************************************************************************/
  3727. VOID
  3728. vSrcOpaqCopyS8D16(
  3729. PBYTE pjSrcIn,
  3730. LONG SrcLeft,
  3731. LONG DeltaSrcIn,
  3732. PBYTE pjDstIn,
  3733. LONG DstLeft,
  3734. LONG DstRight,
  3735. LONG DeltaDstIn,
  3736. LONG cy,
  3737. ULONG uF,
  3738. ULONG uB,
  3739. SURFACE *pS
  3740. )
  3741. {
  3742. USHORT *aus;
  3743. ULONG cusDst = DstRight - DstLeft;
  3744. BLENDINFO bi;
  3745. SEMOBJ so(ghsemEUDC2);
  3746. aus = (USHORT*) pvFillOpaqTableCT(sizeof(*aus), uF, uB, pS, &bi, FALSE);
  3747. pjSrcIn += SrcLeft;
  3748. pjDstIn += DstLeft * sizeof(USHORT);
  3749. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  3750. {
  3751. BYTE *pjSrc = pjSrcIn;
  3752. USHORT *pusDst = (USHORT*) pjDstIn;
  3753. USHORT *pusDstEnd = pusDst + cusDst;
  3754. for ( ; pusDst < pusDstEnd; pusDst++, pjSrc++)
  3755. {
  3756. *pusDst = aus[*pjSrc];
  3757. }
  3758. }
  3759. }
  3760. static
  3761. ULONG FASTCALL ulBlendPixelCT(BLENDINFO *pbi, ULONG uB, const F_RGB *pfrgb)
  3762. {
  3763. ULONG ulRet, ulT;
  3764. LONG lB, dB;
  3765. // shift as ULONG's, store as LONG's.
  3766. lB = pbi->pjGamma[((((uB & pbi->flRed) << pbi->iRedL) >> pbi->iRedR) & 255)];
  3767. dB = pbi->lRedF - lB;
  3768. ulT = BLENDCT(pfrgb->kR, pbi->lRedF, lB, dB);
  3769. ulT = pbi->pjGammaInv[ulT];
  3770. ulRet = (((ulT << pbi->iRedR) >> pbi->iRedL) & pbi->flRed);
  3771. lB = pbi->pjGamma[((((uB & pbi->flGre) << pbi->iGreL) >> pbi->iGreR) & 255)];
  3772. dB = pbi->lGreF - lB;
  3773. ulT = BLENDCT(pfrgb->kG, pbi->lGreF, lB, dB);
  3774. ulT = pbi->pjGammaInv[ulT];
  3775. ulRet |= (((ulT << pbi->iGreR) >> pbi->iGreL) & pbi->flGre);
  3776. lB = pbi->pjGamma[((((uB & pbi->flBlu) << pbi->iBluL) >> pbi->iBluR) & 255)];
  3777. dB = pbi->lBluF - lB;
  3778. ulT = BLENDCT(pfrgb->kB, pbi->lBluF, lB, dB);
  3779. ulT = pbi->pjGammaInv[ulT];
  3780. ulRet |= (((ulT << pbi->iBluR) >> pbi->iBluL) & pbi->flBlu);
  3781. return ulRet;
  3782. }
  3783. VOID
  3784. vSrcTranCopyS8D16New(
  3785. PBYTE pjSrcIn,
  3786. LONG SrcLeft,
  3787. LONG DeltaSrcIn,
  3788. PBYTE pjDstIn,
  3789. LONG DstLeft,
  3790. LONG DstRight,
  3791. LONG DeltaDstIn,
  3792. LONG cy,
  3793. ULONG uF,
  3794. ULONG uB,
  3795. SURFACE *pS,
  3796. FNCOPYALPHABUFFER *pfnCopyAlphaBuffer,
  3797. PBYTE pjCopyBuffer
  3798. )
  3799. {
  3800. USHORT *aus = NULL; // points to lookup table
  3801. LONG cusDst = (LONG)(DstRight - DstLeft);
  3802. BLENDINFO bi;
  3803. ULONG uB0; // background pixel in the upper left corner
  3804. SEMOBJ so(ghsemEUDC2);
  3805. pjSrcIn += SrcLeft;
  3806. pjDstIn += DstLeft * sizeof(USHORT);
  3807. // take the hit, hoping the background will not be variable
  3808. uB0 = uB = *((USHORT *)pjDstIn);
  3809. aus = (USHORT *)pvFillOpaqTableCT(sizeof(USHORT), uF, uB, pS, &bi, TRUE);
  3810. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  3811. {
  3812. BYTE *pjSrc = pjSrcIn;
  3813. USHORT *pusDst = (USHORT*) pjDstIn;
  3814. LONG cx = cusDst;
  3815. USHORT *pusDstNew;
  3816. // copy dst to the temp buffer according to alpha information
  3817. (*pfnCopyAlphaBuffer)(pjSrc, pjDstIn, pjCopyBuffer, cusDst, &pusDstNew);
  3818. for ( ; cx; cx--, pusDst++, pjSrc++, pusDstNew++)
  3819. {
  3820. // if *pjSrc == 0, we do not touch the destination, therefore
  3821. // we do not need to READ the destination and do not need to blend.
  3822. // This is about 68% of the pixels in winstone scenario.
  3823. // Likewise, if *pjSrc == max_index (ie pure foreground), READ
  3824. // operation is not necessary, the only thing we do is WRITE of the
  3825. // foreground to the destination,
  3826. ULONG kSrc = *pjSrc;
  3827. if (kSrc)
  3828. {
  3829. uB = *pusDstNew; // no hit any more on the read
  3830. if (uB == uB0) // 25% of the pixels in winstone
  3831. {
  3832. *pusDst = aus[kSrc]; // background did not change, lucky
  3833. }
  3834. else if (kSrc == (CT_LOOKUP-1)) // 5% of the pixels in winstone
  3835. {
  3836. *pusDst = (USHORT)uF;
  3837. }
  3838. else // auch, must blend, fortunately only 2% on winstone
  3839. {
  3840. *pusDst = (USHORT)ulBlendPixelCT(&bi, uB, &gaOutTable[kSrc]);
  3841. }
  3842. }
  3843. }
  3844. }
  3845. }
  3846. /******************************Public*Routine******************************\
  3847. *
  3848. * Routine Name
  3849. *
  3850. * vCopyAlphaBuffer16bpp
  3851. *
  3852. * Routine Description:
  3853. *
  3854. * This routine copies from 'pjSrc' to 'pjDst' the portions needed for
  3855. * doing blended, as specified by the 'pjAlpha' alpha buffer.
  3856. *
  3857. * The motivation for this routine is that reads from video memory are
  3858. * performance killers, and we want to do reads only where we absolutely
  3859. * need to.
  3860. *
  3861. * I have observed that consecutive word reads from video memory are
  3862. * typically about 4 MB/s on AGP systems; consecutive dword reads are
  3863. * typically about 8 MB/s.
  3864. *
  3865. * This is done as the first pass in the blend operation, in order to
  3866. * get all the reads done first for all the read-modify-write operations
  3867. * implicit in a blend. We very carefully pay attention to the blend
  3868. * buffer we'll be using later to read only those pixels that we'll
  3869. * need.
  3870. *
  3871. * We get 2 benefits:
  3872. *
  3873. * 1. It's easy to combine reads into dword reads. If we need both
  3874. * pixels in a dword, it's twice as fast to do a single dword read
  3875. * as it is to do 2 consecutive word reads.
  3876. * 2. We enable the write portion to be all write-combined, which wouldn't
  3877. * be true if we were doing read-modify-write on a pixel by pixel basis.
  3878. *
  3879. *
  3880. * Arguments:
  3881. *
  3882. * pjAlpha - alpha buffer that is actually the source in the blend
  3883. * operation; this tells us what pixels we'll need to read
  3884. * from the destination of the blend operation
  3885. * pjSrc - actually points to the destination of the blend operation
  3886. * pjDst - points to where we'll store our temporary copy of the
  3887. * destination of the blend operation
  3888. * cx - number of pixels to read
  3889. *
  3890. * Return Value:
  3891. *
  3892. * None
  3893. *
  3894. \**************************************************************************/
  3895. // This macro returns TRUE if the specified alpha value is either
  3896. // completely transparent or completely opaque. In either case, we
  3897. // don't actually need to read the destination.
  3898. //
  3899. // NOTE: For reasons that escape me, the compiler required casts to
  3900. // 'unsigned' even though all the parameters were unsigned.
  3901. #define TRANSLUCENT(a) ((UCHAR) ((a) - 1) < (CT_LOOKUP - 2))
  3902. VOID
  3903. vCopyAlphaBuffer16bpp(
  3904. PBYTE pjAlpha,
  3905. PBYTE pjSrc,
  3906. PBYTE pjDst,
  3907. LONG cx,
  3908. PUSHORT *ppusDstNew
  3909. )
  3910. {
  3911. ULONG cj = (ULONG)(((ULONG_PTR) pjSrc) & 3);
  3912. pjDst += cj;
  3913. *ppusDstNew = (USHORT*)pjDst;
  3914. if (((ULONG_PTR) pjSrc) & 2)
  3915. {
  3916. if (TRANSLUCENT(pjAlpha[0]))
  3917. {
  3918. *((USHORT*) pjDst) = *((USHORT*) pjSrc);
  3919. }
  3920. pjSrc += 2;
  3921. pjDst += 2;
  3922. pjAlpha++;
  3923. cx--;
  3924. }
  3925. while (TRUE)
  3926. {
  3927. cx -= 2;
  3928. if (cx < 0)
  3929. break;
  3930. if (TRANSLUCENT(pjAlpha[0]) || TRANSLUCENT(pjAlpha[1]))
  3931. {
  3932. *((ULONG*) pjDst) = *((ULONG*) pjSrc);
  3933. }
  3934. pjSrc += 4;
  3935. pjDst += 4;
  3936. pjAlpha += 2;
  3937. }
  3938. if (cx & 1)
  3939. {
  3940. if (TRANSLUCENT(pjAlpha[0]))
  3941. {
  3942. *((USHORT*) pjDst) = *((USHORT*) pjSrc);
  3943. }
  3944. }
  3945. }
  3946. /******************************Public*Routine******************************\
  3947. *
  3948. * Routine Name
  3949. *
  3950. * vCopyAlphaBuffer16bppMMX
  3951. *
  3952. * Routine Description:
  3953. *
  3954. * This routine works the same as 'vCopyAlphaBuffer16bpp', except that
  3955. * it will take advantage of MMX 64-bit operations to improve the read
  3956. * speed even more.
  3957. *
  3958. * I have observed that consecutive dword reads from video memory are
  3959. * typically about 8 MB/s on AGP systems; consecutive qword reads are
  3960. * typically about 11 MB/s.
  3961. *
  3962. * IMPORTANT NOTE: The floating point state is expected to have already
  3963. * been saved!
  3964. *
  3965. * Arguments:
  3966. *
  3967. * pjAlpha - alpha buffer that is actually the source in the blend
  3968. * operation; this tells us what pixels we'll need to read
  3969. * from the destination of the blend operation
  3970. * pjSrc - actually points to the destination of the blend operation
  3971. * pjDst - points to where we'll store our temporary copy of the
  3972. * destination of the blend operation
  3973. * cx - number of pixels to read
  3974. *
  3975. * Return Value:
  3976. *
  3977. * None
  3978. *
  3979. \**************************************************************************/
  3980. // Disable the "missing emms" warning. We don't really need to do it in
  3981. // this routine; instead, we do the emms instruction just before we restore
  3982. // the floating point state.
  3983. #pragma warning( disable: 4799 )
  3984. VOID
  3985. vCopyAlphaBuffer16bppMMX(
  3986. PBYTE pjAlpha,
  3987. PBYTE pjSrc,
  3988. PBYTE pjDst,
  3989. LONG cx,
  3990. PUSHORT *ppusDstNew
  3991. )
  3992. {
  3993. ULONG cj = (ULONG)(((ULONG_PTR) pjSrc) & 7);
  3994. pjDst += cj;
  3995. *ppusDstNew = (USHORT*)pjDst;
  3996. if (((ULONG_PTR) pjSrc) & 2)
  3997. {
  3998. if (TRANSLUCENT(pjAlpha[0]))
  3999. {
  4000. *((USHORT*) pjDst) = *((USHORT*) pjSrc);
  4001. }
  4002. pjSrc += 2;
  4003. pjDst += 2;
  4004. pjAlpha++;
  4005. cx--;
  4006. }
  4007. if (((ULONG_PTR) pjSrc) & 4)
  4008. {
  4009. if (cx >= 2)
  4010. {
  4011. cx -= 2;
  4012. if (TRANSLUCENT(pjAlpha[0]) || TRANSLUCENT(pjAlpha[1]))
  4013. {
  4014. *((ULONG*) pjDst) = *((ULONG*) pjSrc);
  4015. }
  4016. pjSrc += 4;
  4017. pjDst += 4;
  4018. pjAlpha += 2;
  4019. }
  4020. }
  4021. while (TRUE)
  4022. {
  4023. cx -= 4;
  4024. if (cx < 0)
  4025. break;
  4026. if (TRANSLUCENT(pjAlpha[0]) || TRANSLUCENT(pjAlpha[1]))
  4027. {
  4028. if (TRANSLUCENT(pjAlpha[2]) || TRANSLUCENT(pjAlpha[3]))
  4029. {
  4030. // Do a 64-bit copy using the MMX registers:
  4031. #if defined(_X86_)
  4032. _asm
  4033. {
  4034. mov esi, pjSrc
  4035. movq mm0, [esi]
  4036. mov esi, pjDst
  4037. movq [esi], mm0
  4038. }
  4039. #endif
  4040. }
  4041. else
  4042. {
  4043. *((ULONG*) pjDst) = *((ULONG*) pjSrc);
  4044. }
  4045. }
  4046. else if (TRANSLUCENT(pjAlpha[2]) || TRANSLUCENT(pjAlpha[3]))
  4047. {
  4048. *((ULONG*) (pjDst + 4)) = *((ULONG*) (pjSrc + 4));
  4049. }
  4050. pjSrc += 8;
  4051. pjDst += 8;
  4052. pjAlpha += 4;
  4053. }
  4054. if (cx & 2)
  4055. {
  4056. if (TRANSLUCENT(pjAlpha[0]) || TRANSLUCENT(pjAlpha[1]))
  4057. {
  4058. *((ULONG*) pjDst) = *((ULONG*) pjSrc);
  4059. }
  4060. pjSrc += 4;
  4061. pjDst += 4;
  4062. pjAlpha += 2;
  4063. }
  4064. if (cx & 1)
  4065. {
  4066. if (TRANSLUCENT(pjAlpha[0]))
  4067. {
  4068. *((USHORT*) pjDst) = *((USHORT*) pjSrc);
  4069. }
  4070. }
  4071. }
  4072. #define COPY_BUFFER_ENTRIES 1000
  4073. #define COPY_BUFFER_SIZE (sizeof(double) * COPY_BUFFER_ENTRIES)
  4074. double gajCopyBuffer[COPY_BUFFER_ENTRIES];
  4075. /******************************Public*Routine******************************\
  4076. *
  4077. * Routine Name
  4078. *
  4079. * vSrcTranCopyS8D16
  4080. *
  4081. * Routine Description:
  4082. *
  4083. * This routine chooses the optimal SrcTranCopy routine for the display,
  4084. * be it 5-5-5 or 5-6-5 or arbitrary. It also chooses the appropriate
  4085. * destination 'copy' routine based on the hardware's capabilities.
  4086. *
  4087. * NOTE: I expect this function to disappear, and this logic moved up
  4088. * higher at some point.
  4089. *
  4090. * Arguments:
  4091. *
  4092. * Return Value:
  4093. *
  4094. * None
  4095. *
  4096. \**************************************************************************/
  4097. VOID
  4098. vSrcTranCopyS8D16(
  4099. PBYTE pjSrcIn,
  4100. LONG SrcLeft,
  4101. LONG DeltaSrcIn,
  4102. PBYTE pjDstIn,
  4103. LONG DstLeft,
  4104. LONG DstRight,
  4105. LONG DeltaDstIn,
  4106. LONG cy,
  4107. ULONG uF,
  4108. ULONG uB,
  4109. SURFACE *pS
  4110. )
  4111. {
  4112. // !!! Note that this isn't thread safe or anything
  4113. BYTE* pjCopyBuffer = (BYTE *)gajCopyBuffer;
  4114. BOOL bAlloc = FALSE;
  4115. ULONG cjNeeded = (DstRight - DstLeft) * sizeof(USHORT) + sizeof(double);
  4116. if (cjNeeded > COPY_BUFFER_SIZE)
  4117. {
  4118. pjCopyBuffer = (PBYTE)PALLOCNOZ(cjNeeded, 'oteG');
  4119. if (!pjCopyBuffer)
  4120. return;
  4121. bAlloc = TRUE;
  4122. }
  4123. #if defined(_X86_)
  4124. if (gbMMXProcessor)
  4125. {
  4126. KFLOATING_SAVE fsFpState;
  4127. // This save operation is quite expensive. We would want to amortize
  4128. // its cost across all the rectangles if there is complex clipping.
  4129. NTSTATUS status = KeSaveFloatingPointState(&fsFpState);
  4130. ASSERTGDI(NT_SUCCESS(status),
  4131. "Unexpected KeSaveFloatingPointState failure");
  4132. vSrcTranCopyS8D16New(pjSrcIn, SrcLeft, DeltaSrcIn, pjDstIn, DstLeft,
  4133. DstRight, DeltaDstIn, cy, uF, uB, pS,
  4134. vCopyAlphaBuffer16bppMMX, pjCopyBuffer);
  4135. // Do the 'emms' instruction now that we're done with all of our
  4136. // MMX operations. I'm not actually sure if we really need to do
  4137. // this because KeRestoreFloatingPointState might handle it anyway,
  4138. // but we're better safe than sorry.
  4139. //
  4140. // NOTE: 'emms' is a very expensive operation.
  4141. _asm emms
  4142. KeRestoreFloatingPointState(&fsFpState);
  4143. }
  4144. else
  4145. #endif
  4146. {
  4147. // We don't have to worry about floating point state in this
  4148. // code path.
  4149. vSrcTranCopyS8D16New(pjSrcIn, SrcLeft, DeltaSrcIn, pjDstIn, DstLeft,
  4150. DstRight, DeltaDstIn, cy, uF, uB, pS,
  4151. vCopyAlphaBuffer16bpp, pjCopyBuffer);
  4152. }
  4153. if (bAlloc)
  4154. VFREEMEM(pjCopyBuffer);
  4155. }
  4156. /******************************Public*Routine******************************\
  4157. * *
  4158. * Routine Name *
  4159. * *
  4160. * vSrcOpaqCopyS8D24 *
  4161. * *
  4162. * Routine Description: *
  4163. * *
  4164. * Arguments: *
  4165. * *
  4166. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  4167. * SrcLeft - left (starting) pixel in src rectangle *
  4168. * DeltaSrcIn - bytes from one src scan line to next *
  4169. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  4170. * DstLeft - left(first) dst pixel *
  4171. * DstRight - right(last) dst pixel *
  4172. * DeltaDstIn - bytes from one Dst scan line to next *
  4173. * cy - number of scan lines *
  4174. * uF - Foreground color *
  4175. * uB - Background color *
  4176. * pS - pointer to destination SURFACE *
  4177. * *
  4178. * Return Value: *
  4179. * *
  4180. * None *
  4181. * *
  4182. \**************************************************************************/
  4183. VOID
  4184. vSrcOpaqCopyS8D24(
  4185. PBYTE pjSrcIn,
  4186. LONG SrcLeft,
  4187. LONG DeltaSrcIn,
  4188. PBYTE pjDstIn,
  4189. LONG DstLeft,
  4190. LONG DstRight,
  4191. LONG DeltaDstIn,
  4192. LONG cy,
  4193. ULONG uF,
  4194. ULONG uB,
  4195. SURFACE *pS
  4196. )
  4197. {
  4198. ULONG *aul; // a cache of the 252 possible 24-bit
  4199. // colors that can be seen on the
  4200. // destination surface.
  4201. ULONG cjDst = 3 * (DstRight - DstLeft);
  4202. BLENDINFO bi;
  4203. SEMOBJ so(ghsemEUDC2);
  4204. aul = (ULONG*) pvFillOpaqTableCT(sizeof(*aul), uF, uB, pS, &bi, FALSE);
  4205. pjSrcIn += SrcLeft ; // 1 pixels per src byte
  4206. pjDstIn += DstLeft * 3; // 3 bytes per dest pixel
  4207. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  4208. {
  4209. BYTE *ajSrc; // points directly into OpaqTable
  4210. BYTE *pjSrc = pjSrcIn;
  4211. BYTE *pjDst = pjDstIn;
  4212. BYTE *pjDstEnd = pjDstIn + cjDst;
  4213. for ( ;pjDst < pjDstEnd; pjSrc++)
  4214. {
  4215. ajSrc = (BYTE*) &aul[*pjSrc];
  4216. *pjDst++ = *ajSrc++;
  4217. *pjDst++ = *ajSrc++;
  4218. *pjDst++ = *ajSrc;
  4219. }
  4220. }
  4221. }
  4222. VOID
  4223. vSrcTranCopyS8D24(
  4224. PBYTE pjSrcIn,
  4225. LONG SrcLeft,
  4226. LONG DeltaSrcIn,
  4227. PBYTE pjDstIn,
  4228. LONG DstLeft,
  4229. LONG DstRight,
  4230. LONG DeltaDstIn,
  4231. LONG cy,
  4232. ULONG uF,
  4233. ULONG uB,
  4234. SURFACE *pS
  4235. )
  4236. {
  4237. BLENDINFO bi;
  4238. ULONG *aul;
  4239. ULONG ulFore = uF & 0xffffff; // 24 bits
  4240. ULONG ulNewFore;
  4241. ULONG uB0;
  4242. SEMOBJ so(ghsemEUDC2);
  4243. ULONG cjDst = 3 * (DstRight - DstLeft);
  4244. pjSrcIn += SrcLeft ; // 1 pixels per src byte
  4245. pjDstIn += DstLeft * 3; // 3 bytes per dest pixel
  4246. // this is real slow, there 3 reads, must optimize
  4247. uB0 = ((ULONG)pjDstIn[0] << 0) |
  4248. ((ULONG)pjDstIn[1] << 8) |
  4249. ((ULONG)pjDstIn[2] << 16) ;
  4250. // precompute the table in case we need it:
  4251. aul = (ULONG*) pvFillOpaqTableCT(sizeof(*aul), uF, uB0, pS, &bi, TRUE);
  4252. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  4253. {
  4254. BYTE *ajSrc; // points directly into OpaqTable
  4255. BYTE *pjSrc = pjSrcIn;
  4256. BYTE *pjDst = pjDstIn;
  4257. BYTE *pjDstEnd = pjDstIn + cjDst;
  4258. for ( ;pjDst < pjDstEnd; pjSrc++)
  4259. {
  4260. if (*pjSrc)
  4261. {
  4262. if (*pjSrc == (CT_LOOKUP-1)) // pure foreground
  4263. {
  4264. ajSrc = (BYTE*)&ulFore;
  4265. }
  4266. else
  4267. {
  4268. uB = ((ULONG)pjDst[0] << 0) |
  4269. ((ULONG)pjDst[1] << 8) |
  4270. ((ULONG)pjDst[2] << 16) ;
  4271. if (uB == uB0)
  4272. {
  4273. ajSrc = (BYTE*) &aul[*pjSrc];
  4274. }
  4275. else // must blend
  4276. {
  4277. ulNewFore = ulBlendPixelCT(&bi, uB, &gaOutTable[*pjSrc]);
  4278. ajSrc = (BYTE*)&ulNewFore;
  4279. }
  4280. }
  4281. *pjDst++ = *ajSrc++;
  4282. *pjDst++ = *ajSrc++;
  4283. *pjDst++ = *ajSrc;
  4284. }
  4285. else
  4286. {
  4287. pjDst += 3; // do not touch the background, just inc position
  4288. }
  4289. }
  4290. }
  4291. }
  4292. /******************************Public*Routine******************************\
  4293. * *
  4294. * Routine Name *
  4295. * *
  4296. * vSrcOpaqCopyS8D32 *
  4297. * *
  4298. * Routine Description: *
  4299. * *
  4300. * Arguments: *
  4301. * *
  4302. * pjSrcIn - pointer to beginning of current scan line of src buffer *
  4303. * SrcLeft - left (starting) pixel in src rectangle *
  4304. * DeltaSrcIn - bytes from one src scan line to next *
  4305. * pjDstIn - pointer to beginning of current scan line of Dst buffer *
  4306. * DstLeft - left(first) dst pixel *
  4307. * DstRight - right(last) dst pixel *
  4308. * DeltaDstIn - bytes from one Dst scan line to next *
  4309. * cy - number of scan lines *
  4310. * uF - Foreground color *
  4311. * uB - Background color *
  4312. * pS - pointer to destination SURFACE *
  4313. * *
  4314. * Return Value: *
  4315. * *
  4316. * None *
  4317. * *
  4318. \**************************************************************************/
  4319. VOID
  4320. vSrcOpaqCopyS8D32(
  4321. PBYTE pjSrcIn,
  4322. LONG SrcLeft,
  4323. LONG DeltaSrcIn,
  4324. PBYTE pjDstIn,
  4325. LONG DstLeft,
  4326. LONG DstRight,
  4327. LONG DeltaDstIn,
  4328. LONG cy,
  4329. ULONG uF,
  4330. ULONG uB,
  4331. SURFACE *pS
  4332. )
  4333. {
  4334. ULONG *aul; // array of 252 possible colors
  4335. ULONG culDst = (DstRight - DstLeft); // * sizeof(ULONG)
  4336. BLENDINFO bi;
  4337. SEMOBJ so(ghsemEUDC2);
  4338. aul = (ULONG*) pvFillOpaqTableCT(sizeof(*aul), uF, uB, pS, &bi, FALSE);
  4339. pjSrcIn += SrcLeft;
  4340. pjDstIn += DstLeft * sizeof(ULONG);
  4341. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  4342. {
  4343. BYTE *pjSrc = pjSrcIn;
  4344. ULONG *pul = (ULONG*) pjDstIn;
  4345. ULONG *pulEnd = pul + culDst;
  4346. for ( ; pul < pulEnd; pul++, pjSrc++)
  4347. {
  4348. *pul = aul[*pjSrc];
  4349. }
  4350. }
  4351. }
  4352. VOID
  4353. vSrcTranCopyS8D32(
  4354. PBYTE pjSrcIn,
  4355. LONG SrcLeft,
  4356. LONG DeltaSrcIn,
  4357. PBYTE pjDstIn,
  4358. LONG DstLeft,
  4359. LONG DstRight,
  4360. LONG DeltaDstIn,
  4361. LONG cy,
  4362. ULONG uF,
  4363. ULONG uB,
  4364. SURFACE *pS
  4365. )
  4366. {
  4367. BLENDINFO bi;
  4368. ULONG *aul;
  4369. ULONG culDst = (DstRight - DstLeft); // * sizeof(ULONG)
  4370. ULONG uB0; // dst pixel at the upper left corner
  4371. SEMOBJ so(ghsemEUDC2);
  4372. pjSrcIn += SrcLeft;
  4373. pjDstIn += DstLeft * sizeof(ULONG);
  4374. // take the hit, hoping the background will not be variable
  4375. uB0 = uB = *((ULONG *)pjDstIn);
  4376. // compute the table, get blending info
  4377. aul = (ULONG*) pvFillOpaqTableCT(sizeof(*aul), uF, uB, pS, &bi, TRUE);
  4378. for (; cy; cy--, pjSrcIn += DeltaSrcIn, pjDstIn += DeltaDstIn)
  4379. {
  4380. BYTE *pjSrc = pjSrcIn;
  4381. ULONG *pul = (ULONG*) pjDstIn;
  4382. ULONG *pulEnd = pul + culDst;
  4383. for ( ; pul < pulEnd; pul++, pjSrc++)
  4384. {
  4385. ULONG kSrc = *pjSrc;
  4386. if (kSrc)
  4387. {
  4388. if (kSrc == (CT_LOOKUP-1)) // pure foreground
  4389. {
  4390. *pul = uF; // just write, no read, no recompute
  4391. }
  4392. else
  4393. {
  4394. // now comes the slow read/modify/write operation on a per pixel basis
  4395. uB = *pul; // read
  4396. if (uB == uB0) // lucky, background did not change
  4397. {
  4398. *pul = aul[kSrc]; // write
  4399. }
  4400. else // blend on the spot
  4401. {
  4402. *pul = ulBlendPixelCT(&bi, uB, &gaOutTable[kSrc]);
  4403. }
  4404. }
  4405. }
  4406. }
  4407. }
  4408. }
  4409. void
  4410. vOrClearTypeGlyph(
  4411. GLYPHBITS* pgb ,
  4412. unsigned dpSrcScan,
  4413. BYTE* pjDstScan,
  4414. unsigned dpDstScan
  4415. )
  4416. {
  4417. BYTE *pjDst, *pjSrc, *pjDstOut, *pjDstScanOut;
  4418. unsigned cy = (unsigned) pgb->sizlBitmap.cy;
  4419. unsigned cx = (unsigned) pgb->sizlBitmap.cx;
  4420. BYTE *pjSrcScan = &(pgb->aj[0]);
  4421. for
  4422. (
  4423. pjDstScanOut = pjDstScan + cy * dpDstScan;
  4424. pjDstScan < pjDstScanOut;
  4425. pjDstScan += dpDstScan, pjSrcScan += dpSrcScan
  4426. )
  4427. {
  4428. pjSrc = pjSrcScan;
  4429. pjDst = pjDstScan;
  4430. for (pjDstOut = pjDst + cx ; pjDst < pjDstOut; pjDst++, pjSrc++)
  4431. {
  4432. if (*pjDst == 0)
  4433. {
  4434. *pjDst = *pjSrc;
  4435. }
  4436. else if (*pjSrc != 0)
  4437. {
  4438. ULONG kR, kG, kB;
  4439. kR = (ULONG)gaOutTable[*pjDst].kR + (ULONG)gaOutTable[*pjSrc].kR;
  4440. kG = (ULONG)gaOutTable[*pjDst].kG + (ULONG)gaOutTable[*pjSrc].kG;
  4441. kB = (ULONG)gaOutTable[*pjDst].kB + (ULONG)gaOutTable[*pjSrc].kB;
  4442. if (kR > CT_SAMPLE_F) {kR = CT_SAMPLE_F;}
  4443. if (kG > CT_SAMPLE_F) {kG = CT_SAMPLE_F;}
  4444. if (kB > CT_SAMPLE_F) {kB = CT_SAMPLE_F;}
  4445. *pjDst = gajStorage1[kB + 7 * kG + 49 * kR];
  4446. }
  4447. }
  4448. }
  4449. }
  4450. // rasterizer returns unfiltered data in 2,2,2 format for r,g,b
  4451. #define GETRED(j) (((j) >> 4) & 3)
  4452. #define GETGRE(j) (((j) >> 2) & 3)
  4453. #define GETBLU(j) (((j) >> 0) & 3)
  4454. #define R_SET(j) ((j) & 0X30)
  4455. #define B_SET(j) ((j) & 0X03)
  4456. #define FL_LEFT_LEAK 1
  4457. #define FL_RIGHT_LEAK 2
  4458. // because of the color filtering we may need to expand the original bitmap
  4459. // by one column of zero pixels on the left and on the right.
  4460. // After we perform the color filtering the column of left edge will pick up
  4461. // a non-trivial Blue component (color "leak" from the leftmost pixel in the
  4462. // original bitmap) while the column on the right edge will pick up the
  4463. // nontrivial Red component from the "leakage" of the rightmost pixel in the
  4464. // original bitmap. [BodinD]
  4465. ULONG ulClearTypeFilter(GLYPHBITS *pgb, GLYPHDATA *pgd, PRFONT prfnt)
  4466. {
  4467. ULONG cx = pgb->sizlBitmap.cx;
  4468. ULONG cy = pgb->sizlBitmap.cy;
  4469. BYTE * pCurrentStorageTable = gajStorageTable;
  4470. if ((cx == 1) && (cy == 1) && (pgb->aj[0] == 0))
  4471. {
  4472. // this is a space glyph
  4473. pgb->sizlBitmap.cx = 0;
  4474. pgb->sizlBitmap.cy = 0;
  4475. return CJ_CTGD(0,0);
  4476. }
  4477. #if DBG
  4478. {
  4479. ULONG cx1 = (ULONG)(pgd->rclInk.right - pgd->rclInk.left);
  4480. ULONG cy1 = (ULONG)(pgd->rclInk.bottom - pgd->rclInk.top);
  4481. ASSERTGDI(cx1 == cx, "cx problem\n");
  4482. ASSERTGDI(cy1 == cy, "cy problem\n");
  4483. }
  4484. #endif // DBG
  4485. if (prfnt->ppfe->pifi->flInfo & (FM_INFO_CONSTANT_WIDTH | FM_INFO_OPTICALLY_FIXED_PITCH) /* the font is fixed pitch */
  4486. && prfnt->cache.bSmallMetrics /* only for horizontal transform */
  4487. && (prfnt->ppfe->pifi->usWinWeight <= FW_NORMAL) /* normal or thin weight */
  4488. &&
  4489. ( !_wcsicmp((PWSTR)((BYTE*)prfnt->ppfe->pifi + prfnt->ppfe->pifi->dpwszFamilyName),L"Courier New")
  4490. || !_wcsicmp((PWSTR)((BYTE*)prfnt->ppfe->pifi + prfnt->ppfe->pifi->dpwszFamilyName),L"Rod")
  4491. || !_wcsicmp((PWSTR)((BYTE*)prfnt->ppfe->pifi + prfnt->ppfe->pifi->dpwszFamilyName),L"Rod Transparent")
  4492. || !_wcsicmp((PWSTR)((BYTE*)prfnt->ppfe->pifi + prfnt->ppfe->pifi->dpwszFamilyName),L"Fixed Miriam Transparent")
  4493. || !_wcsicmp((PWSTR)((BYTE*)prfnt->ppfe->pifi + prfnt->ppfe->pifi->dpwszFamilyName),L"Miriam Fixed")
  4494. || !_wcsicmp((PWSTR)((BYTE*)prfnt->ppfe->pifi + prfnt->ppfe->pifi->dpwszFamilyName),L"Simplified Arabic Fixed")
  4495. )
  4496. )
  4497. {
  4498. /* Courier New look too thin with ClearType standard filter, let's use a bloated filter : */
  4499. pCurrentStorageTable = gajStorageTableBloated;
  4500. }
  4501. FLONG flCTBits = 0;
  4502. ULONG cyT = cy;
  4503. for (BYTE *pjScan = pgb->aj; cyT; cyT--, pjScan += cx)
  4504. {
  4505. if (R_SET(pjScan[0]))
  4506. flCTBits |= FL_LEFT_LEAK;
  4507. if (B_SET(pjScan[cx - 1]))
  4508. flCTBits |= FL_RIGHT_LEAK;
  4509. if ((flCTBits & (FL_LEFT_LEAK | FL_RIGHT_LEAK)) == (FL_LEFT_LEAK | FL_RIGHT_LEAK))
  4510. break;
  4511. }
  4512. // we need to copy and filter in the same pass for performance reasons,
  4513. // we traverse the source backwards, so that we do not overwrite it
  4514. ULONG cxD = cx;
  4515. if (flCTBits & FL_LEFT_LEAK)
  4516. cxD += 1;
  4517. if (flCTBits & FL_RIGHT_LEAK)
  4518. cxD += 1;
  4519. BYTE jP, jT, jN;
  4520. ULONG kBP; // unfiltered blue count from the previous pixel
  4521. ULONG kRN; // unfiltered red count from the next pixel
  4522. ULONG kRT, kGT, kBT; // unfiltered counts from this pixel
  4523. ULONG iStorage;
  4524. BYTE *pjSrcScanEnd;
  4525. BYTE *pjDstScanEnd;
  4526. pjSrcScanEnd = pgb->aj + (cx * cy) - 1;
  4527. pjDstScanEnd = pgb->aj + (cxD * cy) - 1;
  4528. for ( ; pjDstScanEnd > pgb->aj; pjDstScanEnd -= cxD, pjSrcScanEnd -= cx)
  4529. {
  4530. BYTE *pjD1, *pjS1, *pjS0;
  4531. pjD1 = pjDstScanEnd;
  4532. pjS1 = pjSrcScanEnd;
  4533. pjS0 = pjS1 - cx;
  4534. // for the right border pixel jN = 0; jT = 0; jP = *pjS1;
  4535. // therefore:
  4536. //
  4537. // kBP = GETBLU(*pjS1); // GETBLU(jP);
  4538. // kRN = 0; // GETRED(jN);
  4539. // kRT = 0; // GETRED(jT);
  4540. // kGT = 0; // GETGRE(jT);
  4541. // kBT = 0; // GETBLU(jT);
  4542. //
  4543. // now convert this to a filtered index in the lookup table range
  4544. // this is the trick, filtering and storing is done in one step
  4545. // iStorage = kRN + 3 * (kBT + 3 * (kGT + 3 * (kRT + 3 * kBP)));
  4546. if (flCTBits & FL_RIGHT_LEAK)
  4547. {
  4548. *pjD1-- = pCurrentStorageTable[3 * 3 * 3 * 3 * GETBLU(*pjS1)];
  4549. }
  4550. // initialize the loop in the middle
  4551. for (jN = 0, jT = *pjS1; pjS1 > pjS0; pjS1--, pjD1--, jN = jT, jT = jP)
  4552. {
  4553. jP = (pjS1 == &pjS0[1]) ? 0 : pjS1[-1];
  4554. kBP = GETBLU(jP);
  4555. kRN = GETRED(jN);
  4556. if (kBP || jT || kRN) // must compute, else optimize
  4557. {
  4558. kRT = GETRED(jT);
  4559. kGT = GETGRE(jT);
  4560. kBT = GETBLU(jT);
  4561. // now convert this to a filtered index in the lookup table range
  4562. // this is the trick, filtering and storing is done in one step
  4563. iStorage = kRN + 3 * (kBT + 3 * (kGT + 3 * (kRT + 3 * kBP)));
  4564. *pjD1 = pCurrentStorageTable[iStorage];
  4565. }
  4566. else
  4567. {
  4568. *pjD1 = 0;
  4569. }
  4570. }
  4571. // for the left border pixel jP = 0; jT = 0; jN = pjS0[1];
  4572. // therefore:
  4573. //
  4574. // kBP = 0; // GETBLU(jP);
  4575. // kRN = GETRED(pjS0[1]); // GETRED(jN);
  4576. // kRT = 0; // GETRED(jT);
  4577. // kGT = 0; // GETGRE(jT);
  4578. // kBT = 0; // GETBLU(jT);
  4579. //
  4580. // now convert this to a filtered index in the lookup table range
  4581. // this is the trick, filtering and storing is done in one step
  4582. // iStorage = kRN + 3 * (kBT + 3 * (kGT + 3 * (kRT + 3 * kBP)));
  4583. // i.e. iStorage = kRN, which implies:
  4584. if (flCTBits & FL_LEFT_LEAK)
  4585. {
  4586. *pjD1 = pCurrentStorageTable[ GETRED(pjS0[1]) ];
  4587. }
  4588. }
  4589. // fix the size and the origin
  4590. pgb->sizlBitmap.cx = cxD;
  4591. if (flCTBits & FL_LEFT_LEAK)
  4592. pgb->ptlOrigin.x -= 1;
  4593. return CJ_CTGD(cxD, cy);
  4594. }
  4595. /******************************Public*Routine******************************\
  4596. * *
  4597. * Routine Name: *
  4598. * *
  4599. * draw_clrt_nf_ntb_o_to_temp_start *
  4600. * *
  4601. * Routine Description: *
  4602. * *
  4603. * Assembles a cleartype glyph string into a temporary 8bpp right and left*
  4604. * DWORD aligned buffer. This routine assumes a variable pitch font. *
  4605. * *
  4606. * Arguments: *
  4607. * *
  4608. * pGlyphPos - pointer to an array of cGlyph gray GLYPHPOS structures *
  4609. * cGlyphs - count of gray glyphs in array starting at pGlyphPos *
  4610. * pjDstStart - pointer to a 8bpp buffer where string is to be assembled *
  4611. * This buffer is DWORD aligned at the left and right *
  4612. * edges of each scan. *
  4613. * ulLeftEdge - screen coordinate corresponding to the left edge of *
  4614. * the temporary buffer *
  4615. * lDstDelta - count of bytes in each scan of the destination buffer *
  4616. * (this must be a multiple of 4 because the buffer is *
  4617. * DWORD aligned on each scan). *
  4618. * ulCharInc - This must be zero. *
  4619. * ulTempTop - screen coordinate corresponding to the top of the *
  4620. * destination buffer. This is used to convert the *
  4621. * glyph positions on the screen to addresses in the *
  4622. * destination bitmap. *
  4623. * *
  4624. * Return Value: *
  4625. * *
  4626. * None *
  4627. * *
  4628. \**************************************************************************/
  4629. extern "C" VOID draw_clrt_nf_ntb_o_to_temp_start(
  4630. PGLYPHPOS pGlyphPos,
  4631. ULONG cGlyphs,
  4632. PUCHAR pjDstStart,
  4633. ULONG ulLeftEdge,
  4634. ULONG lDstDelta,
  4635. ULONG ulCharInc,
  4636. ULONG ulTempTop
  4637. )
  4638. {
  4639. GLYPHBITS *pgb; // pointer to current GLYPHBITS
  4640. LONG x; // pixel offset of the
  4641. // left edge of the glyph bitmap
  4642. // from the left edge of the
  4643. // output (8-bpp) bitmap
  4644. LONG y; // the pixel offset of the top edge
  4645. // of the glyph bitmap from the top
  4646. // edge of the output bitmap.
  4647. LONG cx; // number of pixels per glyph scan
  4648. // If non zero then the destination
  4649. // bitmap is out of alignment with
  4650. // the source glyph by a one nyble
  4651. // shift and a single byte of the
  4652. // source will affect two consecutive
  4653. // bytes of the destination.
  4654. LONG cy;
  4655. BYTE *pjSrc;
  4656. LONG lDstSkip;
  4657. ULONG kR;
  4658. ULONG kG;
  4659. ULONG kB;
  4660. LONG i;
  4661. do {
  4662. pgb = pGlyphPos->pgdf->pgb;
  4663. x = pGlyphPos->ptl.x + pgb->ptlOrigin.x - ulLeftEdge;
  4664. y = pGlyphPos->ptl.y + pgb->ptlOrigin.y - ulTempTop;
  4665. ASSERTGDI(x >=0,"draw_clrt_nf_ntb_o_to_temp_start x < 0" );
  4666. ASSERTGDI(y >=0,"draw_clrt_nf_ntb_o_to_temp_start y < 0" );
  4667. cy = pgb->sizlBitmap.cy;
  4668. if (cy)
  4669. {
  4670. BYTE *pjDst = pjDstStart + (y * lDstDelta) + x;
  4671. cx = pgb->sizlBitmap.cx;
  4672. lDstSkip = lDstDelta - cx;
  4673. pjSrc = &pgb->aj[0];
  4674. do {
  4675. i = cx;
  4676. do {
  4677. if (*pjDst == 0)
  4678. {
  4679. *pjDst = *pjSrc;
  4680. }
  4681. else if (*pjSrc != 0)
  4682. {
  4683. kR = (ULONG)gaOutTable[*pjDst].kR + (ULONG)gaOutTable[*pjSrc].kR;
  4684. kG = (ULONG)gaOutTable[*pjDst].kG + (ULONG)gaOutTable[*pjSrc].kG;
  4685. kB = (ULONG)gaOutTable[*pjDst].kB + (ULONG)gaOutTable[*pjSrc].kB;
  4686. if (kR > CT_SAMPLE_F) {kR = CT_SAMPLE_F;}
  4687. if (kG > CT_SAMPLE_F) {kG = CT_SAMPLE_F;}
  4688. if (kB > CT_SAMPLE_F) {kB = CT_SAMPLE_F;}
  4689. *pjDst = gajStorage1[kB + 7 * kG + 49 * kR];
  4690. }
  4691. pjDst++;
  4692. pjSrc++;
  4693. } while (--i != 0);
  4694. pjDst += lDstSkip;
  4695. } while (--cy != 0);
  4696. }
  4697. pGlyphPos++;
  4698. } while (--cGlyphs != 0);
  4699. }
  4700. /******************************Public*Routine******************************\
  4701. * *
  4702. * Routine Name: *
  4703. * *
  4704. * draw_clrt_f_ntb_o_to_temp_start *
  4705. * *
  4706. * Routine Description: *
  4707. * *
  4708. * Assembles a cleartype glyph string into a temporary 4bpp right and left*
  4709. * DWORD aligned buffer. This routine assumes a fixed pitch font with *
  4710. * character increment equal to ulCharInc *
  4711. * *
  4712. * Arguments: *
  4713. * *
  4714. * pGlyphPos - pointer to an array of cGlyph gray GLYPHPOS structures *
  4715. * cGlyphs - count of gray glyphs in array starting at pGlyphPos *
  4716. * pjDst - pointer to a 8bpp buffer where string is to be assembled *
  4717. * This buffer is DWORD aligned at the left and right *
  4718. * edges of each scan. *
  4719. * ulLeftEdge - screen coordinate corresponding to the left edge of *
  4720. * the temporary buffer *
  4721. * dpDst - count of bytes in each scan of the destination buffer *
  4722. * (this must be a multiple of 4 because the buffer is *
  4723. * DWORD aligned on each scan). *
  4724. * ulCharInc - must NOT be zero in this case *
  4725. * ulTempTop - screen coordinate corresponding to the top of the *
  4726. * destination buffer. This is used to convert the *
  4727. * glyph positions on the screen to addresses in the *
  4728. * destination bitmap. *
  4729. * *
  4730. * Return Value: *
  4731. * *
  4732. * None *
  4733. * *
  4734. \**************************************************************************/
  4735. extern "C" VOID draw_clrt_f_ntb_o_to_temp_start(
  4736. PGLYPHPOS pGlyphPos,
  4737. ULONG cGlyphs,
  4738. PUCHAR pjDst,
  4739. ULONG ulLeftEdge,
  4740. ULONG dpDst,
  4741. ULONG ulCharInc,
  4742. ULONG ulTempTop
  4743. )
  4744. {
  4745. GLYPHBITS *pgb; // pointer to current GLYPHBITS
  4746. int x; // x-coordinate of the current
  4747. // character origin with respect
  4748. // to the upper left pixel of the
  4749. // output (4-bpp) bitmap
  4750. int y; // y-coordinate of the current
  4751. // character origin with respect
  4752. // to the upper left pixel of the
  4753. // output (4-bpp) bitmap
  4754. unsigned cx; // number of pixels per glyph scan
  4755. // If non zero then the destination
  4756. // bitmap is out of alignment with
  4757. // the source glyph by a one nyble
  4758. // shift and a single byte of the
  4759. // source will affect two consecutive
  4760. // bytes of the destination.
  4761. GLYPHPOS *pgpOut; // sentinel for loop
  4762. BYTE *pj; // pointer into Buffer corresponding
  4763. // to the upper left pixel of the
  4764. // current gray glyph
  4765. // (x,y) = position of first CHARACTER ORIGIN with respect to
  4766. // the upper left pixel of the destination 4bpp bitmap
  4767. x = pGlyphPos->ptl.x - ulLeftEdge;
  4768. y = pGlyphPos->ptl.y - ulTempTop;
  4769. for (pgpOut = pGlyphPos + cGlyphs; pGlyphPos < pgpOut; x += ulCharInc, pGlyphPos++)
  4770. {
  4771. int xT, yT; // position of UPPER LEFT pixel of glyph
  4772. // with respect to the upper left pixel
  4773. // of the bitmap.
  4774. pgb = pGlyphPos->pgdf->pgb;
  4775. xT = x + pgb->ptlOrigin.x;
  4776. yT = y + pgb->ptlOrigin.y;
  4777. cx = (unsigned) pgb->sizlBitmap.cx;
  4778. pj = pjDst + (yT * dpDst) + xT;
  4779. vOrClearTypeGlyph(pgb, cx, pj, dpDst);
  4780. }
  4781. }
  4782. BYTE ajGammaCT_10[256] = {
  4783. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  4784. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  4785. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  4786. 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
  4787. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  4788. 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
  4789. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  4790. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  4791. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  4792. 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
  4793. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  4794. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
  4795. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  4796. 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
  4797. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  4798. 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  4799. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  4800. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  4801. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  4802. 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
  4803. 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
  4804. 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
  4805. 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
  4806. 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
  4807. 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
  4808. 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
  4809. 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
  4810. 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
  4811. 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
  4812. 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
  4813. 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  4814. 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  4815. };
  4816. BYTE ajGammaCT_11[256] = {
  4817. 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05,
  4818. 0x06, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0A, 0x0B,
  4819. 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x10, 0x11, 0x12,
  4820. 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19,
  4821. 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x1F, 0x20,
  4822. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  4823. 0x29, 0x2A, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
  4824. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  4825. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3E,
  4826. 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
  4827. 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
  4828. 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
  4829. 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
  4830. 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
  4831. 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
  4832. 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
  4833. 0x77, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  4834. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  4835. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  4836. 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98,
  4837. 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0,
  4838. 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA9,
  4839. 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1,
  4840. 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xBA,
  4841. 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
  4842. 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB,
  4843. 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3,
  4844. 0xD4, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC,
  4845. 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE3, 0xE4, 0xE5,
  4846. 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
  4847. 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
  4848. 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  4849. };
  4850. BYTE ajGammaInvCT_11[256] = {
  4851. 0x00, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, 0x0A,
  4852. 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13,
  4853. 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D,
  4854. 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26,
  4855. 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
  4856. 0x2F, 0x30, 0x31, 0x33, 0x34, 0x35, 0x36, 0x37,
  4857. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  4858. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48,
  4859. 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
  4860. 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
  4861. 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,
  4862. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
  4863. 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
  4864. 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  4865. 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80,
  4866. 0x81, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  4867. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  4868. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  4869. 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9C, 0x9D, 0x9E,
  4870. 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
  4871. 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE,
  4872. 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
  4873. 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD,
  4874. 0xBE, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4,
  4875. 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC,
  4876. 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3,
  4877. 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA,
  4878. 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
  4879. 0xE3, 0xE4, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
  4880. 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xEF, 0xF0,
  4881. 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
  4882. 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  4883. };
  4884. BYTE ajGammaCT_12[256] = {
  4885. 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03,
  4886. 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09,
  4887. 0x09, 0x0A, 0x0B, 0x0B, 0x0C, 0x0D, 0x0D, 0x0E,
  4888. 0x0F, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14,
  4889. 0x15, 0x16, 0x17, 0x18, 0x18, 0x19, 0x1A, 0x1B,
  4890. 0x1C, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
  4891. 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28,
  4892. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
  4893. 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  4894. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3E,
  4895. 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
  4896. 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
  4897. 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
  4898. 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
  4899. 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
  4900. 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
  4901. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  4902. 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  4903. 0x80, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
  4904. 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x90, 0x91,
  4905. 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
  4906. 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2,
  4907. 0xA3, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB,
  4908. 0xAC, 0xAD, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4,
  4909. 0xB5, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD,
  4910. 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC7,
  4911. 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCF, 0xD0,
  4912. 0xD1, 0xD2, 0xD3, 0xD4, 0xD6, 0xD7, 0xD8, 0xD9,
  4913. 0xDA, 0xDB, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
  4914. 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xEA, 0xEB, 0xEC,
  4915. 0xED, 0xEE, 0xEF, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
  4916. 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF
  4917. };
  4918. BYTE ajGammaInvCT_12[256] = {
  4919. 0x00, 0x03, 0x04, 0x06, 0x08, 0x0A, 0x0B, 0x0D,
  4920. 0x0E, 0x10, 0x11, 0x13, 0x14, 0x15, 0x17, 0x18,
  4921. 0x19, 0x1B, 0x1C, 0x1D, 0x1F, 0x20, 0x21, 0x22,
  4922. 0x24, 0x25, 0x26, 0x27, 0x28, 0x2A, 0x2B, 0x2C,
  4923. 0x2D, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
  4924. 0x36, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
  4925. 0x3F, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  4926. 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x50,
  4927. 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
  4928. 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,
  4929. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
  4930. 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
  4931. 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  4932. 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80,
  4933. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  4934. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  4935. 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  4936. 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9D,
  4937. 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5,
  4938. 0xA6, 0xA7, 0xA8, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC,
  4939. 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB1, 0xB2, 0xB3,
  4940. 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xB9, 0xBA,
  4941. 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC1,
  4942. 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC8,
  4943. 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF,
  4944. 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD5, 0xD6,
  4945. 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDB, 0xDC, 0xDD,
  4946. 0xDE, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4,
  4947. 0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB,
  4948. 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2,
  4949. 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF7, 0xF8,
  4950. 0xF9, 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF
  4951. };
  4952. BYTE ajGammaCT_13[256] = {
  4953. 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02,
  4954. 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06,
  4955. 0x07, 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0B, 0x0B,
  4956. 0x0C, 0x0C, 0x0D, 0x0E, 0x0E, 0x0F, 0x10, 0x10,
  4957. 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x15, 0x16,
  4958. 0x17, 0x18, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1C,
  4959. 0x1D, 0x1E, 0x1F, 0x1F, 0x20, 0x21, 0x22, 0x23,
  4960. 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x29,
  4961. 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x2F, 0x30,
  4962. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
  4963. 0x39, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  4964. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  4965. 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4C, 0x4D, 0x4E,
  4966. 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
  4967. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
  4968. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  4969. 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x70,
  4970. 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  4971. 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
  4972. 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8A,
  4973. 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x92, 0x93,
  4974. 0x94, 0x95, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
  4975. 0x9D, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA6,
  4976. 0xA7, 0xA8, 0xA9, 0xAA, 0xAC, 0xAD, 0xAE, 0xAF,
  4977. 0xB0, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB8, 0xB9,
  4978. 0xBA, 0xBB, 0xBC, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
  4979. 0xC4, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC,
  4980. 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5, 0xD6,
  4981. 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDE, 0xDF, 0xE0,
  4982. 0xE2, 0xE3, 0xE4, 0xE5, 0xE7, 0xE8, 0xE9, 0xEA,
  4983. 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF3, 0xF5,
  4984. 0xF6, 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF
  4985. };
  4986. BYTE ajGammaInvCT_13[256] = {
  4987. 0x00, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
  4988. 0x12, 0x13, 0x15, 0x17, 0x18, 0x1A, 0x1B, 0x1D,
  4989. 0x1E, 0x20, 0x21, 0x23, 0x24, 0x25, 0x27, 0x28,
  4990. 0x29, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x31, 0x32,
  4991. 0x34, 0x35, 0x36, 0x37, 0x39, 0x3A, 0x3B, 0x3C,
  4992. 0x3D, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
  4993. 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
  4994. 0x4F, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  4995. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
  4996. 0x60, 0x61, 0x62, 0x63, 0x64, 0x66, 0x67, 0x68,
  4997. 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
  4998. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  4999. 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  5000. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x86,
  5001. 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
  5002. 0x8F, 0x90, 0x91, 0x92, 0x92, 0x93, 0x94, 0x95,
  5003. 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9B, 0x9C,
  5004. 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA3,
  5005. 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA,
  5006. 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1,
  5007. 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB6, 0xB7, 0xB8,
  5008. 0xB9, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBF,
  5009. 0xC0, 0xC1, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6,
  5010. 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC,
  5011. 0xCD, 0xCE, 0xCF, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3,
  5012. 0xD4, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD8, 0xD9,
  5013. 0xDA, 0xDB, 0xDC, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0,
  5014. 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE6,
  5015. 0xE7, 0xE8, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xEC,
  5016. 0xED, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3,
  5017. 0xF3, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF8, 0xF9,
  5018. 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF
  5019. };
  5020. BYTE ajGammaCT_14[256] = {
  5021. 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
  5022. 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05,
  5023. 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09,
  5024. 0x09, 0x0A, 0x0A, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D,
  5025. 0x0E, 0x0F, 0x0F, 0x10, 0x10, 0x11, 0x12, 0x12,
  5026. 0x13, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18,
  5027. 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1E,
  5028. 0x1F, 0x1F, 0x20, 0x21, 0x22, 0x22, 0x23, 0x24,
  5029. 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
  5030. 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x31,
  5031. 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
  5032. 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
  5033. 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
  5034. 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
  5035. 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
  5036. 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,
  5037. 0x61, 0x62, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69,
  5038. 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
  5039. 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
  5040. 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x84,
  5041. 0x85, 0x86, 0x87, 0x88, 0x89, 0x8B, 0x8C, 0x8D,
  5042. 0x8E, 0x8F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x97,
  5043. 0x98, 0x99, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA0,
  5044. 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA8, 0xA9, 0xAA,
  5045. 0xAB, 0xAD, 0xAE, 0xAF, 0xB0, 0xB2, 0xB3, 0xB4,
  5046. 0xB5, 0xB7, 0xB8, 0xB9, 0xBB, 0xBC, 0xBD, 0xBE,
  5047. 0xC0, 0xC1, 0xC2, 0xC4, 0xC5, 0xC6, 0xC8, 0xC9,
  5048. 0xCA, 0xCB, 0xCD, 0xCE, 0xCF, 0xD1, 0xD2, 0xD3,
  5049. 0xD5, 0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDD, 0xDE,
  5050. 0xDF, 0xE1, 0xE2, 0xE3, 0xE5, 0xE6, 0xE8, 0xE9,
  5051. 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF4,
  5052. 0xF5, 0xF7, 0xF8, 0xF9, 0xFB, 0xFC, 0xFE, 0xFF
  5053. };
  5054. BYTE ajGammaInvCT_14[256] = {
  5055. 0x00, 0x05, 0x08, 0x0B, 0x0D, 0x0F, 0x12, 0x14,
  5056. 0x16, 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20, 0x22,
  5057. 0x23, 0x25, 0x26, 0x28, 0x29, 0x2B, 0x2C, 0x2E,
  5058. 0x2F, 0x31, 0x32, 0x33, 0x35, 0x36, 0x37, 0x39,
  5059. 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x40, 0x41, 0x43,
  5060. 0x44, 0x45, 0x46, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
  5061. 0x4D, 0x4E, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
  5062. 0x56, 0x57, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
  5063. 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
  5064. 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
  5065. 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
  5066. 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
  5067. 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x85,
  5068. 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D,
  5069. 0x8E, 0x8F, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94,
  5070. 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B,
  5071. 0x9C, 0x9D, 0x9E, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2,
  5072. 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,
  5073. 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xAF,
  5074. 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB4, 0xB5, 0xB6,
  5075. 0xB7, 0xB8, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBC,
  5076. 0xBD, 0xBE, 0xBF, 0xC0, 0xC0, 0xC1, 0xC2, 0xC3,
  5077. 0xC4, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC8, 0xC9,
  5078. 0xCA, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF,
  5079. 0xD0, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD5, 0xD6,
  5080. 0xD6, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDB, 0xDC,
  5081. 0xDC, 0xDD, 0xDE, 0xDF, 0xDF, 0xE0, 0xE1, 0xE2,
  5082. 0xE2, 0xE3, 0xE4, 0xE5, 0xE5, 0xE6, 0xE7, 0xE8,
  5083. 0xE8, 0xE9, 0xEA, 0xEB, 0xEB, 0xEC, 0xED, 0xEE,
  5084. 0xEE, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3,
  5085. 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF8, 0xF9, 0xF9,
  5086. 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF
  5087. };
  5088. BYTE ajGammaCT_15[256] = {
  5089. 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
  5090. 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
  5091. 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07,
  5092. 0x07, 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B,
  5093. 0x0B, 0x0C, 0x0C, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F,
  5094. 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x14,
  5095. 0x15, 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1A,
  5096. 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1E, 0x1F, 0x1F,
  5097. 0x20, 0x21, 0x22, 0x22, 0x23, 0x24, 0x25, 0x25,
  5098. 0x26, 0x27, 0x28, 0x29, 0x29, 0x2A, 0x2B, 0x2C,
  5099. 0x2D, 0x2E, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
  5100. 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
  5101. 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x41,
  5102. 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
  5103. 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
  5104. 0x52, 0x53, 0x54, 0x55, 0x56, 0x58, 0x59, 0x5A,
  5105. 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62,
  5106. 0x63, 0x64, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B,
  5107. 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74,
  5108. 0x75, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7E,
  5109. 0x7F, 0x80, 0x81, 0x82, 0x84, 0x85, 0x86, 0x87,
  5110. 0x88, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x90, 0x91,
  5111. 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x9A, 0x9B,
  5112. 0x9C, 0x9E, 0x9F, 0xA0, 0xA1, 0xA3, 0xA4, 0xA5,
  5113. 0xA7, 0xA8, 0xA9, 0xAB, 0xAC, 0xAD, 0xAE, 0xB0,
  5114. 0xB1, 0xB2, 0xB4, 0xB5, 0xB6, 0xB8, 0xB9, 0xBB,
  5115. 0xBC, 0xBD, 0xBF, 0xC0, 0xC1, 0xC3, 0xC4, 0xC5,
  5116. 0xC7, 0xC8, 0xCA, 0xCB, 0xCC, 0xCE, 0xCF, 0xD1,
  5117. 0xD2, 0xD3, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDC,
  5118. 0xDD, 0xDF, 0xE0, 0xE2, 0xE3, 0xE4, 0xE6, 0xE7,
  5119. 0xE9, 0xEA, 0xEC, 0xED, 0xEF, 0xF0, 0xF2, 0xF3,
  5120. 0xF5, 0xF6, 0xF8, 0xF9, 0xFB, 0xFC, 0xFE, 0xFF
  5121. };
  5122. BYTE ajGammaInvCT_15[256] = {
  5123. 0x00, 0x06, 0x0A, 0x0D, 0x10, 0x13, 0x15, 0x17,
  5124. 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x23, 0x25, 0x27,
  5125. 0x28, 0x2A, 0x2C, 0x2D, 0x2F, 0x30, 0x32, 0x33,
  5126. 0x35, 0x36, 0x38, 0x39, 0x3A, 0x3C, 0x3D, 0x3F,
  5127. 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, 0x48, 0x49,
  5128. 0x4A, 0x4B, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x53,
  5129. 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5B, 0x5C,
  5130. 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64,
  5131. 0x65, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
  5132. 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
  5133. 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
  5134. 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84,
  5135. 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8A, 0x8B,
  5136. 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x92,
  5137. 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99,
  5138. 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0x9F, 0xA0,
  5139. 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7,
  5140. 0xA8, 0xA9, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD,
  5141. 0xAE, 0xAF, 0xB0, 0xB1, 0xB1, 0xB2, 0xB3, 0xB4,
  5142. 0xB5, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xB9, 0xBA,
  5143. 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC0,
  5144. 0xC1, 0xC2, 0xC3, 0xC3, 0xC4, 0xC5, 0xC6, 0xC6,
  5145. 0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCC, 0xCC,
  5146. 0xCD, 0xCE, 0xCF, 0xCF, 0xD0, 0xD1, 0xD2, 0xD2,
  5147. 0xD3, 0xD4, 0xD5, 0xD5, 0xD6, 0xD7, 0xD7, 0xD8,
  5148. 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD, 0xDE,
  5149. 0xDF, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4,
  5150. 0xE4, 0xE5, 0xE6, 0xE6, 0xE7, 0xE8, 0xE8, 0xE9,
  5151. 0xEA, 0xEB, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF,
  5152. 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF4, 0xF4,
  5153. 0xF5, 0xF6, 0xF6, 0xF7, 0xF8, 0xF8, 0xF9, 0xFA,
  5154. 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF
  5155. };
  5156. BYTE ajGammaCT_16[256] = {
  5157. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
  5158. 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03,
  5159. 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
  5160. 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x09,
  5161. 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D,
  5162. 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, 0x10, 0x10, 0x11,
  5163. 0x12, 0x12, 0x13, 0x13, 0x14, 0x15, 0x15, 0x16,
  5164. 0x17, 0x17, 0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1B,
  5165. 0x1C, 0x1D, 0x1D, 0x1E, 0x1F, 0x1F, 0x20, 0x21,
  5166. 0x22, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27,
  5167. 0x28, 0x29, 0x2A, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
  5168. 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
  5169. 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
  5170. 0x3D, 0x3E, 0x3F, 0x40, 0x40, 0x41, 0x42, 0x43,
  5171. 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
  5172. 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x53, 0x54,
  5173. 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C,
  5174. 0x5D, 0x5E, 0x5F, 0x61, 0x62, 0x63, 0x64, 0x65,
  5175. 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
  5176. 0x6F, 0x71, 0x72, 0x73, 0x74, 0x75, 0x77, 0x78,
  5177. 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7F, 0x80, 0x82,
  5178. 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8A, 0x8C,
  5179. 0x8D, 0x8E, 0x8F, 0x91, 0x92, 0x93, 0x95, 0x96,
  5180. 0x97, 0x99, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA1,
  5181. 0xA2, 0xA3, 0xA5, 0xA6, 0xA7, 0xA9, 0xAA, 0xAB,
  5182. 0xAD, 0xAE, 0xB0, 0xB1, 0xB2, 0xB4, 0xB5, 0xB7,
  5183. 0xB8, 0xB9, 0xBB, 0xBC, 0xBE, 0xBF, 0xC1, 0xC2,
  5184. 0xC4, 0xC5, 0xC6, 0xC8, 0xC9, 0xCB, 0xCC, 0xCE,
  5185. 0xCF, 0xD1, 0xD2, 0xD4, 0xD5, 0xD7, 0xD8, 0xDA,
  5186. 0xDB, 0xDD, 0xDE, 0xE0, 0xE1, 0xE3, 0xE4, 0xE6,
  5187. 0xE7, 0xE9, 0xEB, 0xEC, 0xEE, 0xEF, 0xF1, 0xF2,
  5188. 0xF4, 0xF5, 0xF7, 0xF9, 0xFA, 0xFC, 0xFD, 0xFF
  5189. };
  5190. BYTE ajGammaInvCT_16[256] = {
  5191. 0x00, 0x08, 0x0C, 0x10, 0x13, 0x16, 0x18, 0x1B,
  5192. 0x1D, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2B,
  5193. 0x2D, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x37, 0x39,
  5194. 0x3A, 0x3C, 0x3D, 0x3F, 0x40, 0x42, 0x43, 0x44,
  5195. 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x4E, 0x4F,
  5196. 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57, 0x59,
  5197. 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x61, 0x62,
  5198. 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
  5199. 0x6B, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73,
  5200. 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B,
  5201. 0x7C, 0x7D, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82,
  5202. 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
  5203. 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91,
  5204. 0x92, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
  5205. 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9E,
  5206. 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA5,
  5207. 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB,
  5208. 0xAC, 0xAD, 0xAE, 0xAF, 0xAF, 0xB0, 0xB1, 0xB2,
  5209. 0xB2, 0xB3, 0xB4, 0xB5, 0xB5, 0xB6, 0xB7, 0xB8,
  5210. 0xB9, 0xB9, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE,
  5211. 0xBF, 0xBF, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4,
  5212. 0xC4, 0xC5, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xCA,
  5213. 0xCA, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF,
  5214. 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD5,
  5215. 0xD6, 0xD6, 0xD7, 0xD8, 0xD8, 0xD9, 0xDA, 0xDA,
  5216. 0xDB, 0xDC, 0xDC, 0xDD, 0xDE, 0xDE, 0xDF, 0xE0,
  5217. 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE5, 0xE5,
  5218. 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB,
  5219. 0xEB, 0xEC, 0xEC, 0xED, 0xEE, 0xEE, 0xEF, 0xF0,
  5220. 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF4, 0xF4, 0xF5,
  5221. 0xF6, 0xF6, 0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA,
  5222. 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF
  5223. };
  5224. BYTE ajGammaCT_17[256] = {
  5225. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  5226. 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
  5227. 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04,
  5228. 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07,
  5229. 0x07, 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0A,
  5230. 0x0B, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D, 0x0E, 0x0E,
  5231. 0x0F, 0x0F, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13,
  5232. 0x13, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x18,
  5233. 0x18, 0x19, 0x1A, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D,
  5234. 0x1E, 0x1E, 0x1F, 0x20, 0x21, 0x21, 0x22, 0x23,
  5235. 0x24, 0x24, 0x25, 0x26, 0x27, 0x27, 0x28, 0x29,
  5236. 0x2A, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
  5237. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  5238. 0x38, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
  5239. 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
  5240. 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E,
  5241. 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
  5242. 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
  5243. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x69,
  5244. 0x6A, 0x6B, 0x6C, 0x6D, 0x6F, 0x70, 0x71, 0x72,
  5245. 0x73, 0x75, 0x76, 0x77, 0x78, 0x7A, 0x7B, 0x7C,
  5246. 0x7D, 0x7F, 0x80, 0x81, 0x83, 0x84, 0x85, 0x86,
  5247. 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x90, 0x91,
  5248. 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, 0x9B, 0x9C,
  5249. 0x9D, 0x9F, 0xA0, 0xA2, 0xA3, 0xA4, 0xA6, 0xA7,
  5250. 0xA9, 0xAA, 0xAC, 0xAD, 0xAE, 0xB0, 0xB1, 0xB3,
  5251. 0xB4, 0xB6, 0xB7, 0xB9, 0xBA, 0xBC, 0xBD, 0xBF,
  5252. 0xC0, 0xC2, 0xC3, 0xC5, 0xC6, 0xC8, 0xC9, 0xCB,
  5253. 0xCD, 0xCE, 0xD0, 0xD1, 0xD3, 0xD4, 0xD6, 0xD8,
  5254. 0xD9, 0xDB, 0xDC, 0xDE, 0xE0, 0xE1, 0xE3, 0xE4,
  5255. 0xE6, 0xE8, 0xE9, 0xEB, 0xED, 0xEE, 0xF0, 0xF2,
  5256. 0xF3, 0xF5, 0xF7, 0xF8, 0xFA, 0xFC, 0xFD, 0xFF
  5257. };
  5258. BYTE ajGammaInvCT_17[256] = {
  5259. 0x00, 0x0A, 0x0F, 0x13, 0x16, 0x19, 0x1C, 0x1F,
  5260. 0x21, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30,
  5261. 0x32, 0x34, 0x36, 0x37, 0x39, 0x3B, 0x3C, 0x3E,
  5262. 0x40, 0x41, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4A,
  5263. 0x4B, 0x4D, 0x4E, 0x4F, 0x51, 0x52, 0x53, 0x54,
  5264. 0x56, 0x57, 0x58, 0x59, 0x5B, 0x5C, 0x5D, 0x5E,
  5265. 0x5F, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  5266. 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
  5267. 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  5268. 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80,
  5269. 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87,
  5270. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  5271. 0x90, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  5272. 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9C,
  5273. 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3,
  5274. 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA8, 0xA9,
  5275. 0xAA, 0xAB, 0xAC, 0xAC, 0xAD, 0xAE, 0xAF, 0xAF,
  5276. 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB4, 0xB5, 0xB5,
  5277. 0xB6, 0xB7, 0xB8, 0xB8, 0xB9, 0xBA, 0xBB, 0xBB,
  5278. 0xBC, 0xBD, 0xBE, 0xBE, 0xBF, 0xC0, 0xC0, 0xC1,
  5279. 0xC2, 0xC3, 0xC3, 0xC4, 0xC5, 0xC5, 0xC6, 0xC7,
  5280. 0xC7, 0xC8, 0xC9, 0xCA, 0xCA, 0xCB, 0xCC, 0xCC,
  5281. 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD2,
  5282. 0xD2, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7,
  5283. 0xD8, 0xD8, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC,
  5284. 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE2,
  5285. 0xE2, 0xE3, 0xE3, 0xE4, 0xE5, 0xE5, 0xE6, 0xE7,
  5286. 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC,
  5287. 0xEC, 0xED, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1,
  5288. 0xF1, 0xF2, 0xF2, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5,
  5289. 0xF6, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, 0xFA, 0xFA,
  5290. 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
  5291. };
  5292. // 1.8 gamma tables, we use these as default for now
  5293. BYTE ajGammaCT_18[256] = {
  5294. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5295. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
  5296. 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
  5297. 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06,
  5298. 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09,
  5299. 0x09, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C,
  5300. 0x0D, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, 0x10, 0x10,
  5301. 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x15,
  5302. 0x15, 0x16, 0x16, 0x17, 0x18, 0x18, 0x19, 0x1A,
  5303. 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1E, 0x1E, 0x1F,
  5304. 0x20, 0x20, 0x21, 0x22, 0x23, 0x23, 0x24, 0x25,
  5305. 0x26, 0x26, 0x27, 0x28, 0x29, 0x29, 0x2A, 0x2B,
  5306. 0x2C, 0x2D, 0x2E, 0x2E, 0x2F, 0x30, 0x31, 0x32,
  5307. 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39,
  5308. 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41,
  5309. 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
  5310. 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
  5311. 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5A,
  5312. 0x5B, 0x5C, 0x5D, 0x5F, 0x60, 0x61, 0x62, 0x63,
  5313. 0x64, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
  5314. 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x74, 0x76, 0x77,
  5315. 0x78, 0x7A, 0x7B, 0x7C, 0x7E, 0x7F, 0x80, 0x81,
  5316. 0x83, 0x84, 0x86, 0x87, 0x88, 0x8A, 0x8B, 0x8C,
  5317. 0x8E, 0x8F, 0x91, 0x92, 0x93, 0x95, 0x96, 0x98,
  5318. 0x99, 0x9A, 0x9C, 0x9D, 0x9F, 0xA0, 0xA2, 0xA3,
  5319. 0xA5, 0xA6, 0xA8, 0xA9, 0xAB, 0xAC, 0xAE, 0xAF,
  5320. 0xB1, 0xB2, 0xB4, 0xB5, 0xB7, 0xB8, 0xBA, 0xBC,
  5321. 0xBD, 0xBF, 0xC0, 0xC2, 0xC3, 0xC5, 0xC7, 0xC8,
  5322. 0xCA, 0xCC, 0xCD, 0xCF, 0xD0, 0xD2, 0xD4, 0xD5,
  5323. 0xD7, 0xD9, 0xDA, 0xDC, 0xDE, 0xE0, 0xE1, 0xE3,
  5324. 0xE5, 0xE6, 0xE8, 0xEA, 0xEC, 0xED, 0xEF, 0xF1,
  5325. 0xF3, 0xF4, 0xF6, 0xF8, 0xFA, 0xFB, 0xFD, 0xFF
  5326. };
  5327. BYTE ajGammaInvCT_18[256] = {
  5328. 0x00, 0x0C, 0x11, 0x16, 0x19, 0x1D, 0x20, 0x23,
  5329. 0x25, 0x28, 0x2A, 0x2C, 0x2F, 0x31, 0x33, 0x35,
  5330. 0x37, 0x39, 0x3A, 0x3C, 0x3E, 0x40, 0x41, 0x43,
  5331. 0x45, 0x46, 0x48, 0x49, 0x4B, 0x4C, 0x4E, 0x4F,
  5332. 0x50, 0x52, 0x53, 0x55, 0x56, 0x57, 0x59, 0x5A,
  5333. 0x5B, 0x5C, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x64,
  5334. 0x65, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
  5335. 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
  5336. 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
  5337. 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
  5338. 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8B, 0x8C,
  5339. 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x92, 0x93,
  5340. 0x94, 0x95, 0x96, 0x97, 0x98, 0x98, 0x99, 0x9A,
  5341. 0x9B, 0x9C, 0x9D, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1,
  5342. 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA5, 0xA6, 0xA7,
  5343. 0xA8, 0xA9, 0xA9, 0xAA, 0xAB, 0xAC, 0xAC, 0xAD,
  5344. 0xAE, 0xAF, 0xAF, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3,
  5345. 0xB4, 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9,
  5346. 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBF,
  5347. 0xBF, 0xC0, 0xC1, 0xC1, 0xC2, 0xC3, 0xC3, 0xC4,
  5348. 0xC5, 0xC6, 0xC6, 0xC7, 0xC8, 0xC8, 0xC9, 0xCA,
  5349. 0xCA, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF,
  5350. 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4,
  5351. 0xD5, 0xD5, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9,
  5352. 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD, 0xDE, 0xDE,
  5353. 0xDF, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3,
  5354. 0xE4, 0xE4, 0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8,
  5355. 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC, 0xEC, 0xED,
  5356. 0xED, 0xEE, 0xEE, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1,
  5357. 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6,
  5358. 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB,
  5359. 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
  5360. };
  5361. BYTE ajGammaCT_19[256] = {
  5362. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5363. 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  5364. 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
  5365. 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05,
  5366. 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07,
  5367. 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0A, 0x0A,
  5368. 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0E,
  5369. 0x0E, 0x0F, 0x0F, 0x10, 0x10, 0x11, 0x11, 0x12,
  5370. 0x12, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16,
  5371. 0x17, 0x18, 0x18, 0x19, 0x1A, 0x1A, 0x1B, 0x1C,
  5372. 0x1C, 0x1D, 0x1E, 0x1E, 0x1F, 0x20, 0x20, 0x21,
  5373. 0x22, 0x23, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27,
  5374. 0x28, 0x29, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
  5375. 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
  5376. 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
  5377. 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
  5378. 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
  5379. 0x4D, 0x4E, 0x4F, 0x51, 0x52, 0x53, 0x54, 0x55,
  5380. 0x56, 0x57, 0x58, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
  5381. 0x5F, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67, 0x68,
  5382. 0x69, 0x6A, 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72,
  5383. 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7D,
  5384. 0x7E, 0x7F, 0x81, 0x82, 0x84, 0x85, 0x86, 0x88,
  5385. 0x89, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x92, 0x93,
  5386. 0x95, 0x96, 0x98, 0x99, 0x9B, 0x9C, 0x9E, 0x9F,
  5387. 0xA1, 0xA2, 0xA4, 0xA5, 0xA7, 0xA8, 0xAA, 0xAC,
  5388. 0xAD, 0xAF, 0xB0, 0xB2, 0xB4, 0xB5, 0xB7, 0xB8,
  5389. 0xBA, 0xBC, 0xBD, 0xBF, 0xC1, 0xC2, 0xC4, 0xC6,
  5390. 0xC7, 0xC9, 0xCB, 0xCC, 0xCE, 0xD0, 0xD2, 0xD3,
  5391. 0xD5, 0xD7, 0xD9, 0xDA, 0xDC, 0xDE, 0xE0, 0xE1,
  5392. 0xE3, 0xE5, 0xE7, 0xE9, 0xEB, 0xEC, 0xEE, 0xF0,
  5393. 0xF2, 0xF4, 0xF6, 0xF7, 0xF9, 0xFB, 0xFD, 0xFF
  5394. };
  5395. BYTE ajGammaInvCT_19[256] = {
  5396. 0x00, 0x0E, 0x14, 0x19, 0x1D, 0x20, 0x23, 0x26,
  5397. 0x29, 0x2C, 0x2E, 0x31, 0x33, 0x35, 0x37, 0x39,
  5398. 0x3B, 0x3D, 0x3F, 0x41, 0x43, 0x45, 0x46, 0x48,
  5399. 0x4A, 0x4B, 0x4D, 0x4E, 0x50, 0x51, 0x53, 0x54,
  5400. 0x56, 0x57, 0x58, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F,
  5401. 0x60, 0x61, 0x63, 0x64, 0x65, 0x66, 0x68, 0x69,
  5402. 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72,
  5403. 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
  5404. 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82,
  5405. 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
  5406. 0x8B, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91,
  5407. 0x92, 0x93, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
  5408. 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9D, 0x9E,
  5409. 0x9F, 0xA0, 0xA1, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5,
  5410. 0xA5, 0xA6, 0xA7, 0xA8, 0xA8, 0xA9, 0xAA, 0xAB,
  5411. 0xAB, 0xAC, 0xAD, 0xAE, 0xAE, 0xAF, 0xB0, 0xB1,
  5412. 0xB1, 0xB2, 0xB3, 0xB4, 0xB4, 0xB5, 0xB6, 0xB6,
  5413. 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBB, 0xBC,
  5414. 0xBD, 0xBD, 0xBE, 0xBF, 0xC0, 0xC0, 0xC1, 0xC2,
  5415. 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7,
  5416. 0xC8, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC,
  5417. 0xCD, 0xCD, 0xCE, 0xCF, 0xCF, 0xD0, 0xD1, 0xD1,
  5418. 0xD2, 0xD2, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6, 0xD6,
  5419. 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB,
  5420. 0xDC, 0xDC, 0xDD, 0xDD, 0xDE, 0xDF, 0xDF, 0xE0,
  5421. 0xE0, 0xE1, 0xE2, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4,
  5422. 0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9,
  5423. 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xEE,
  5424. 0xEE, 0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF2, 0xF2,
  5425. 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6,
  5426. 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB,
  5427. 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
  5428. };
  5429. BYTE ajGammaCT_20[256] = {
  5430. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5431. 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
  5432. 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
  5433. 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
  5434. 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06,
  5435. 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09,
  5436. 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C,
  5437. 0x0C, 0x0D, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, 0x10,
  5438. 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14,
  5439. 0x14, 0x15, 0x15, 0x16, 0x17, 0x17, 0x18, 0x18,
  5440. 0x19, 0x1A, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1E,
  5441. 0x1E, 0x1F, 0x20, 0x20, 0x21, 0x22, 0x23, 0x23,
  5442. 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x2A,
  5443. 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x2F, 0x30,
  5444. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
  5445. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  5446. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  5447. 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
  5448. 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
  5449. 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x61, 0x62, 0x63,
  5450. 0x64, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
  5451. 0x6F, 0x70, 0x71, 0x73, 0x74, 0x75, 0x77, 0x78,
  5452. 0x79, 0x7B, 0x7C, 0x7E, 0x7F, 0x80, 0x82, 0x83,
  5453. 0x85, 0x86, 0x88, 0x89, 0x8B, 0x8C, 0x8E, 0x8F,
  5454. 0x91, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9A, 0x9B,
  5455. 0x9D, 0x9E, 0xA0, 0xA2, 0xA3, 0xA5, 0xA6, 0xA8,
  5456. 0xAA, 0xAB, 0xAD, 0xAF, 0xB0, 0xB2, 0xB4, 0xB5,
  5457. 0xB7, 0xB9, 0xBA, 0xBC, 0xBE, 0xC0, 0xC1, 0xC3,
  5458. 0xC5, 0xC7, 0xC8, 0xCA, 0xCC, 0xCE, 0xCF, 0xD1,
  5459. 0xD3, 0xD5, 0xD7, 0xD9, 0xDA, 0xDC, 0xDE, 0xE0,
  5460. 0xE2, 0xE4, 0xE6, 0xE8, 0xE9, 0xEB, 0xED, 0xEF,
  5461. 0xF1, 0xF3, 0xF5, 0xF7, 0xF9, 0xFB, 0xFD, 0xFF
  5462. };
  5463. BYTE ajGammaInvCT_20[256] = {
  5464. 0x00, 0x10, 0x17, 0x1C, 0x20, 0x24, 0x27, 0x2A,
  5465. 0x2D, 0x30, 0x32, 0x35, 0x37, 0x3A, 0x3C, 0x3E,
  5466. 0x40, 0x42, 0x44, 0x46, 0x47, 0x49, 0x4B, 0x4D,
  5467. 0x4E, 0x50, 0x51, 0x53, 0x54, 0x56, 0x57, 0x59,
  5468. 0x5A, 0x5C, 0x5D, 0x5E, 0x60, 0x61, 0x62, 0x64,
  5469. 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
  5470. 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
  5471. 0x77, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  5472. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  5473. 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
  5474. 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95,
  5475. 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
  5476. 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2,
  5477. 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8,
  5478. 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE,
  5479. 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4,
  5480. 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA,
  5481. 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
  5482. 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4,
  5483. 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9,
  5484. 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE,
  5485. 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3,
  5486. 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8,
  5487. 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
  5488. 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1,
  5489. 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6,
  5490. 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA,
  5491. 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE,
  5492. 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3,
  5493. 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
  5494. 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB,
  5495. 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
  5496. };
  5497. BYTE ajGammaCT_21[256] = {
  5498. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5499. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
  5500. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
  5501. 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
  5502. 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05,
  5503. 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07,
  5504. 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0A, 0x0A,
  5505. 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D, 0x0E,
  5506. 0x0E, 0x0E, 0x0F, 0x0F, 0x10, 0x10, 0x11, 0x11,
  5507. 0x12, 0x12, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16,
  5508. 0x16, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1B,
  5509. 0x1B, 0x1C, 0x1D, 0x1D, 0x1E, 0x1F, 0x1F, 0x20,
  5510. 0x21, 0x21, 0x22, 0x23, 0x24, 0x24, 0x25, 0x26,
  5511. 0x27, 0x28, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2C,
  5512. 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x33,
  5513. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
  5514. 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,
  5515. 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4B, 0x4C,
  5516. 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x53, 0x54, 0x55,
  5517. 0x56, 0x57, 0x58, 0x5A, 0x5B, 0x5C, 0x5D, 0x5F,
  5518. 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x68, 0x69,
  5519. 0x6A, 0x6B, 0x6D, 0x6E, 0x70, 0x71, 0x72, 0x74,
  5520. 0x75, 0x76, 0x78, 0x79, 0x7B, 0x7C, 0x7E, 0x7F,
  5521. 0x81, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8B,
  5522. 0x8D, 0x8E, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97,
  5523. 0x99, 0x9B, 0x9C, 0x9E, 0xA0, 0xA1, 0xA3, 0xA5,
  5524. 0xA6, 0xA8, 0xAA, 0xAB, 0xAD, 0xAF, 0xB0, 0xB2,
  5525. 0xB4, 0xB6, 0xB7, 0xB9, 0xBB, 0xBD, 0xBF, 0xC0,
  5526. 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCB, 0xCD, 0xCF,
  5527. 0xD1, 0xD3, 0xD5, 0xD7, 0xD9, 0xDB, 0xDD, 0xDF,
  5528. 0xE1, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
  5529. 0xF1, 0xF3, 0xF5, 0xF7, 0xF9, 0xFB, 0xFD, 0xFF
  5530. };
  5531. BYTE ajGammaInvCT_21[256] = {
  5532. 0x00, 0x12, 0x19, 0x1F, 0x23, 0x27, 0x2B, 0x2E,
  5533. 0x31, 0x34, 0x37, 0x39, 0x3B, 0x3E, 0x40, 0x42,
  5534. 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x4F, 0x51,
  5535. 0x53, 0x54, 0x56, 0x58, 0x59, 0x5B, 0x5C, 0x5D,
  5536. 0x5F, 0x60, 0x62, 0x63, 0x64, 0x66, 0x67, 0x68,
  5537. 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72,
  5538. 0x73, 0x74, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7B,
  5539. 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83,
  5540. 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B,
  5541. 0x8C, 0x8D, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
  5542. 0x93, 0x94, 0x95, 0x95, 0x96, 0x97, 0x98, 0x99,
  5543. 0x9A, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0x9F,
  5544. 0xA0, 0xA1, 0xA2, 0xA3, 0xA3, 0xA4, 0xA5, 0xA6,
  5545. 0xA6, 0xA7, 0xA8, 0xA9, 0xA9, 0xAA, 0xAB, 0xAC,
  5546. 0xAC, 0xAD, 0xAE, 0xAF, 0xAF, 0xB0, 0xB1, 0xB1,
  5547. 0xB2, 0xB3, 0xB4, 0xB4, 0xB5, 0xB6, 0xB6, 0xB7,
  5548. 0xB8, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC,
  5549. 0xBD, 0xBE, 0xBE, 0xBF, 0xC0, 0xC0, 0xC1, 0xC2,
  5550. 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC5, 0xC6, 0xC7,
  5551. 0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCA, 0xCB, 0xCC,
  5552. 0xCC, 0xCD, 0xCD, 0xCE, 0xCF, 0xCF, 0xD0, 0xD0,
  5553. 0xD1, 0xD2, 0xD2, 0xD3, 0xD3, 0xD4, 0xD5, 0xD5,
  5554. 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA,
  5555. 0xDA, 0xDB, 0xDB, 0xDC, 0xDD, 0xDD, 0xDE, 0xDE,
  5556. 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE2, 0xE2, 0xE3,
  5557. 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, 0xE6, 0xE7,
  5558. 0xE7, 0xE8, 0xE8, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB,
  5559. 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE, 0xEF, 0xEF,
  5560. 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3,
  5561. 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7, 0xF7,
  5562. 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB,
  5563. 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF
  5564. };
  5565. BYTE ajGammaCT_22[256] = {
  5566. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  5567. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  5568. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  5569. 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  5570. 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04,
  5571. 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06,
  5572. 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09,
  5573. 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C,
  5574. 0x0C, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F,
  5575. 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13,
  5576. 0x14, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18,
  5577. 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D,
  5578. 0x1E, 0x1E, 0x1F, 0x20, 0x21, 0x21, 0x22, 0x23,
  5579. 0x23, 0x24, 0x25, 0x26, 0x27, 0x27, 0x28, 0x29,
  5580. 0x2A, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
  5581. 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  5582. 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  5583. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  5584. 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51,
  5585. 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5A,
  5586. 0x5B, 0x5D, 0x5E, 0x5F, 0x61, 0x62, 0x63, 0x64,
  5587. 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6F,
  5588. 0x71, 0x72, 0x74, 0x75, 0x77, 0x78, 0x79, 0x7B,
  5589. 0x7C, 0x7E, 0x7F, 0x81, 0x82, 0x84, 0x85, 0x87,
  5590. 0x89, 0x8A, 0x8C, 0x8D, 0x8F, 0x91, 0x92, 0x94,
  5591. 0x95, 0x97, 0x99, 0x9A, 0x9C, 0x9E, 0x9F, 0xA1,
  5592. 0xA3, 0xA5, 0xA6, 0xA8, 0xAA, 0xAC, 0xAD, 0xAF,
  5593. 0xB1, 0xB3, 0xB5, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE,
  5594. 0xC0, 0xC2, 0xC4, 0xC5, 0xC7, 0xC9, 0xCB, 0xCD,
  5595. 0xCF, 0xD1, 0xD3, 0xD5, 0xD7, 0xD9, 0xDB, 0xDD,
  5596. 0xDF, 0xE1, 0xE3, 0xE5, 0xE7, 0xEA, 0xEC, 0xEE,
  5597. 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0xFF
  5598. };
  5599. BYTE ajGammaInvCT_22[256] = {
  5600. 0x00, 0x15, 0x1C, 0x22, 0x27, 0x2B, 0x2E, 0x32,
  5601. 0x35, 0x38, 0x3B, 0x3D, 0x40, 0x42, 0x44, 0x46,
  5602. 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x55,
  5603. 0x57, 0x59, 0x5A, 0x5C, 0x5D, 0x5F, 0x60, 0x62,
  5604. 0x63, 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6D,
  5605. 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x76,
  5606. 0x77, 0x78, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  5607. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  5608. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  5609. 0x90, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  5610. 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9C,
  5611. 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3,
  5612. 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8, 0xA9,
  5613. 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF,
  5614. 0xAF, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB4, 0xB4,
  5615. 0xB5, 0xB6, 0xB6, 0xB7, 0xB8, 0xB8, 0xB9, 0xBA,
  5616. 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
  5617. 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC3, 0xC4,
  5618. 0xC5, 0xC5, 0xC6, 0xC7, 0xC7, 0xC8, 0xC8, 0xC9,
  5619. 0xCA, 0xCA, 0xCB, 0xCB, 0xCC, 0xCD, 0xCD, 0xCE,
  5620. 0xCE, 0xCF, 0xCF, 0xD0, 0xD1, 0xD1, 0xD2, 0xD2,
  5621. 0xD3, 0xD4, 0xD4, 0xD5, 0xD5, 0xD6, 0xD6, 0xD7,
  5622. 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDB,
  5623. 0xDC, 0xDC, 0xDD, 0xDD, 0xDE, 0xDF, 0xDF, 0xE0,
  5624. 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE3, 0xE4,
  5625. 0xE4, 0xE5, 0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8,
  5626. 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC,
  5627. 0xEC, 0xED, 0xED, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0,
  5628. 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4,
  5629. 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7, 0xF7, 0xF8,
  5630. 0xF8, 0xF9, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB,
  5631. 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF
  5632. };
  5633. VOID vGetBlendInfo (
  5634. ULONG size, SURFACE *pS, // input
  5635. ULONG uF, // foreground color
  5636. BLENDINFO *pbi // output
  5637. )
  5638. {
  5639. BLENDINFO bi; // local for faster reference
  5640. XEPALOBJ xpo;
  5641. PDEVOBJ pdo(pS->hdev());
  5642. if(pS->pPal == NULL)
  5643. {
  5644. xpo.ppalSet(pdo.ppalSurf());
  5645. }
  5646. else
  5647. {
  5648. xpo.ppalSet(pS->pPal);
  5649. }
  5650. ASSERTGDI(xpo.bValid(), "Invalid XEPALOBJ" );
  5651. if (xpo.bIsBitfields())
  5652. {
  5653. bi.flRed = xpo.flRed();
  5654. bi.flGre = xpo.flGre();
  5655. bi.flBlu = xpo.flBlu();
  5656. bi.iRedR = (int) (xpo.cRedRight() + xpo.cRedMiddle() - 8);
  5657. bi.iGreR = (int) (xpo.cGreRight() + xpo.cGreMiddle() - 8);
  5658. bi.iBluR = (int) (xpo.cBluRight() + xpo.cBluMiddle() - 8);
  5659. }
  5660. else
  5661. {
  5662. int cBits;
  5663. ULONG flBits;
  5664. if (size == sizeof(USHORT))
  5665. {
  5666. // assumes standard RGB is 5+5+5 for 16-bit color
  5667. cBits = 5;
  5668. flBits = 0x1f;
  5669. }
  5670. else
  5671. {
  5672. cBits = 8;
  5673. flBits = 0xff;
  5674. }
  5675. if (xpo.bIsRGB())
  5676. {
  5677. bi.flRed = flBits;
  5678. bi.flGre = bi.flRed << cBits;
  5679. bi.flBlu = bi.flGre << cBits;
  5680. bi.iRedR = cBits - 8;
  5681. bi.iGreR = bi.iRedR + cBits;
  5682. bi.iBluR = bi.iGreR + cBits;
  5683. }
  5684. else if (xpo.bIsBGR())
  5685. {
  5686. bi.flBlu = flBits;
  5687. bi.flGre = bi.flBlu << cBits;
  5688. bi.flRed = bi.flGre << cBits;
  5689. bi.iBluR = cBits - 8;
  5690. bi.iGreR = bi.iBluR + cBits;
  5691. bi.iRedR = bi.iGreR + cBits;
  5692. }
  5693. else
  5694. {
  5695. RIP("Palette format not supported\n");
  5696. }
  5697. }
  5698. /***************************************************************
  5699. * *
  5700. * Now I shall calculate the shift numbers. *
  5701. * *
  5702. * I shall explain the shift numbers for the red channel. *
  5703. * The green and blue channels are treated in the same way. *
  5704. * *
  5705. * I want to shift the red bits of the red channel colors *
  5706. * so that the most significant bit of the red channel *
  5707. * bits corresponds to a value of 2^7. This means that *
  5708. * if I mask off all of the other color bits, then I *
  5709. * will end up with a number between zero and 255. This *
  5710. * process of going to the 0 .. 255 range looks like *
  5711. * *
  5712. * ((color & flRed) << iRedL) >> iRedR *
  5713. * *
  5714. * Only one of iRedL or iRedR is non zero. *
  5715. * *
  5716. * I then use this number to index into a 256 element *
  5717. * gamma correction table. The gamma correction table *
  5718. * elements are BYTE values that are in the range 0 .. 255. *
  5719. * *
  5720. ***************************************************************/
  5721. bi.iRedL = 0;
  5722. if (bi.iRedR < 0)
  5723. {
  5724. bi.iRedL = - bi.iRedR;
  5725. bi.iRedR = 0;
  5726. }
  5727. bi.iGreL = 0;
  5728. if (bi.iGreR < 0)
  5729. {
  5730. bi.iGreL = - bi.iGreR;
  5731. bi.iGreR = 0;
  5732. }
  5733. bi.iBluL = 0;
  5734. if (bi.iBluR < 0)
  5735. {
  5736. bi.iBluL = - bi.iBluR;
  5737. bi.iBluR = 0;
  5738. }
  5739. // set gamma, default value is 1.5, a bit low to ensure contrast for thin fonts
  5740. // from the color point of view 1.8 might be better
  5741. ULONG ulGamma;
  5742. if (gulGamma != DEFAULT_CT_CONTRAST)
  5743. {
  5744. ulGamma = gulGamma; // overridden via registry or debugger
  5745. }
  5746. else
  5747. {
  5748. ulGamma = pdo.ulGamma();
  5749. if (ulGamma == 0) // the driver did not set it, we set it to our default
  5750. ulGamma = DEFAULT_CT_CONTRAST;
  5751. }
  5752. if (ulGamma < 1100)
  5753. {
  5754. bi.pjGamma = ajGammaCT_10;
  5755. bi.pjGammaInv = ajGammaCT_10;
  5756. }
  5757. else if (ulGamma < 1200)
  5758. {
  5759. bi.pjGamma = ajGammaCT_11;
  5760. bi.pjGammaInv = ajGammaInvCT_11;
  5761. }
  5762. else if (ulGamma < 1300)
  5763. {
  5764. bi.pjGamma = ajGammaCT_12;
  5765. bi.pjGammaInv = ajGammaInvCT_12;
  5766. }
  5767. else if (ulGamma < 1400)
  5768. {
  5769. bi.pjGamma = ajGammaCT_13;
  5770. bi.pjGammaInv = ajGammaInvCT_13;
  5771. }
  5772. else if (ulGamma < 1500)
  5773. {
  5774. bi.pjGamma = ajGammaCT_14;
  5775. bi.pjGammaInv = ajGammaInvCT_14;
  5776. }
  5777. else if (ulGamma < 1600)
  5778. {
  5779. bi.pjGamma = ajGammaCT_15;
  5780. bi.pjGammaInv = ajGammaInvCT_15;
  5781. }
  5782. else if (ulGamma < 1700)
  5783. {
  5784. bi.pjGamma = ajGammaCT_16;
  5785. bi.pjGammaInv = ajGammaInvCT_16;
  5786. }
  5787. else if (ulGamma < 1800)
  5788. {
  5789. bi.pjGamma = ajGammaCT_17;
  5790. bi.pjGammaInv = ajGammaInvCT_17;
  5791. }
  5792. else if (ulGamma < 1900)
  5793. {
  5794. bi.pjGamma = ajGammaCT_18;
  5795. bi.pjGammaInv = ajGammaInvCT_18;
  5796. }
  5797. else if (ulGamma < 2000)
  5798. {
  5799. bi.pjGamma = ajGammaCT_19;
  5800. bi.pjGammaInv = ajGammaInvCT_19;
  5801. }
  5802. else if (ulGamma < 2100)
  5803. {
  5804. bi.pjGamma = ajGammaCT_20;
  5805. bi.pjGammaInv = ajGammaInvCT_20;
  5806. }
  5807. else if (ulGamma < 2200)
  5808. {
  5809. bi.pjGamma = ajGammaCT_21;
  5810. bi.pjGammaInv = ajGammaInvCT_21;
  5811. }
  5812. else
  5813. {
  5814. bi.pjGamma = ajGammaCT_22;
  5815. bi.pjGammaInv = ajGammaInvCT_22;
  5816. }
  5817. // important; shift as ULONG's, store back as LONG's
  5818. // gamma correct at the same step
  5819. bi.lRedF = bi.pjGamma[((((uF & bi.flRed) << bi.iRedL) >> bi.iRedR) & 255)];
  5820. bi.lGreF = bi.pjGamma[((((uF & bi.flGre) << bi.iGreL) >> bi.iGreR) & 255)];
  5821. bi.lBluF = bi.pjGamma[((((uF & bi.flBlu) << bi.iBluL) >> bi.iBluR) & 255)];
  5822. // done, copy out, this is faster than doing pbi->xxx all the time...
  5823. *pbi = bi;
  5824. }
  5825. // default value for few sgi monitors that we have seen
  5826. // Actually, it closer to 2.0, but if the monitor is viewed from
  5827. // a non 90 degree angle, than effective gamma goes as low as 1.2,
  5828. // so we decided to undercompensate and set it to 1.8, slightly below ideal
  5829. VOID *pvFillOpaqTableCT(
  5830. ULONG size,
  5831. ULONG uF,
  5832. ULONG uB,
  5833. SURFACE *pS,
  5834. BLENDINFO *pbi,
  5835. BOOL bTransparent
  5836. )
  5837. {
  5838. // I have been assured of two things....
  5839. // 1) Since this routine is a child of EngTextOut then there
  5840. // will be only one thread in this routine at any one time.
  5841. // This means that I do not need to protect the color
  5842. // table, aulCacheCT[] with a critical section
  5843. // 2) I have been assured that the format of a surface
  5844. // is unique. Thus if the handle of the surface matches
  5845. // the handle of the cached color table, then the
  5846. // formats of the surface are the same.
  5847. BOOL bLookupTableOk = (pS->hGet() == hCacheCT) &&
  5848. (uB == uBCacheCT) &&
  5849. (uF == uFCacheCT) &&
  5850. (gulGamma == uGammaCacheCT) ;
  5851. if (bLookupTableOk && !bTransparent) // do not need to do anything, done
  5852. {
  5853. ASSERTGDI(size == sizeCacheCT, "size != sizeCacheCT\n");
  5854. }
  5855. else
  5856. {
  5857. vGetBlendInfo(size, pS, uF, pbi);
  5858. if (!bLookupTableOk) // need to recompute the lookup table
  5859. {
  5860. vClearTypeLookupTableLoop(size, pS, pbi, uF, uB);
  5861. }
  5862. }
  5863. return (PVOID)aulCacheCT;
  5864. }
  5865. VOID GreSetLCDOrientation(DWORD dwOrientation)
  5866. {
  5867. gaOutTable = (dwOrientation & FE_FONTSMOOTHINGORIENTATIONRGB) ? gaOutTableRGB : gaOutTableBGR;
  5868. }