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.

1690 lines
37 KiB

  1. /**INC+**********************************************************************/
  2. /* Header: wxlint.c */
  3. /* */
  4. /* Purpose: Glyph drawing - internal Windows specific */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1997 */
  7. /* */
  8. /****************************************************************************/
  9. #include <adcg.h>
  10. extern "C" {
  11. #define TRC_GROUP TRC_GROUP_CORE
  12. #define TRC_FILE "wxlint"
  13. #include <atrcapi.h>
  14. }
  15. #include <wxlint.h>
  16. #include <wxldata.h>
  17. #define CALC_WRITE_SIZE( REPS, R, INC ) (LONG)(((REPS)-1)*(INC) + (R))
  18. #define CHECK_CALC_END( CALC_END, TRUE_END ) \
  19. if ((CALC_END) > (TRUE_END)) { \
  20. TRC_ABORT((TB, _T("glyph draw off end of buffer [calcEnd=0x%x trueEnd=0x%x]"), (CALC_END), (TRUE_END))); \
  21. DC_QUIT; \
  22. }
  23. //
  24. // debug routine
  25. //
  26. VOID
  27. exit_fast_text(
  28. LONG cyGlyph,
  29. LONG RightRot,
  30. LONG ulBufDelta,
  31. PDCUINT8 pGlyph,
  32. PDCUINT8 pEndGlyph,
  33. PDCUINT8 pBuffer,
  34. PDCUINT8 pEndBuffer,
  35. LONG cxGlyph
  36. )
  37. {
  38. DC_IGNORE_PARAMETER(cyGlyph);
  39. DC_IGNORE_PARAMETER(RightRot);
  40. DC_IGNORE_PARAMETER(ulBufDelta);
  41. DC_IGNORE_PARAMETER(pGlyph);
  42. DC_IGNORE_PARAMETER(pEndGlyph);
  43. DC_IGNORE_PARAMETER(pBuffer);
  44. DC_IGNORE_PARAMETER(pEndBuffer);
  45. DC_IGNORE_PARAMETER(cxGlyph);
  46. return;
  47. }
  48. //
  49. // or_all_1_wide_rotated_need_last::
  50. // or_all_1_wide_rotated_no_last::
  51. // or_first_1_wide_rotated_need_last
  52. // or_first_1_wide_rotated_no_last::
  53. //
  54. VOID
  55. or_all_1_wide_rotated_need_last(
  56. LONG cyGlyph,
  57. LONG RightRot,
  58. LONG ulBufDelta,
  59. PDCUINT8 pGlyph,
  60. PDCUINT8 pEndGlyph,
  61. PDCUINT8 pBuffer,
  62. PDCUINT8 pEndBuffer,
  63. LONG cxGlyph
  64. )
  65. {
  66. DC_BEGIN_FN("or_all_1_wide_rotated_need_last");
  67. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  68. DCUINT8 c;
  69. CHECK_CALC_END( pjEnd, pEndGlyph );
  70. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 1, ulBufDelta),
  71. (TB, _T("Write into temp buffer off end")));
  72. DC_IGNORE_PARAMETER(cxGlyph);
  73. while (pGlyph != pjEnd) {
  74. c = *pGlyph++;
  75. *pBuffer |= c >> RightRot;
  76. pBuffer += ulBufDelta;
  77. }
  78. DC_EXIT_POINT:
  79. return;
  80. }
  81. //
  82. // mov_first_1_wide_rotated_need_last::
  83. // mov_first_1_wide_rotated_no_last::
  84. //
  85. VOID
  86. mov_first_1_wide_rotated_need_last(
  87. LONG cyGlyph,
  88. LONG RightRot,
  89. LONG ulBufDelta,
  90. PDCUINT8 pGlyph,
  91. PDCUINT8 pEndGlyph,
  92. PDCUINT8 pBuffer,
  93. PDCUINT8 pEndBuffer,
  94. LONG cxGlyph
  95. )
  96. {
  97. DC_BEGIN_FN("mov_first_1_wide_rotated_need_last");
  98. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  99. DCUINT8 c;
  100. CHECK_CALC_END( pjEnd, pEndGlyph );
  101. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 1, ulBufDelta),
  102. (TB, _T("Write into temp buffer off end")));
  103. DC_IGNORE_PARAMETER(cxGlyph);
  104. while (pGlyph != pjEnd) {
  105. c = *pGlyph++;
  106. *pBuffer = (DCUINT8)(c >> RightRot);
  107. pBuffer += ulBufDelta;
  108. }
  109. DC_EXIT_POINT:
  110. return;
  111. }
  112. //
  113. // mov_first_1_wide_unrotated::
  114. //
  115. VOID
  116. mov_first_1_wide_unrotated(
  117. LONG cyGlyph,
  118. LONG RightRot,
  119. LONG ulBufDelta,
  120. PDCUINT8 pGlyph,
  121. PDCUINT8 pEndGlyph,
  122. PDCUINT8 pBuffer,
  123. PDCUINT8 pEndBuffer,
  124. LONG cxGlyph
  125. )
  126. {
  127. DC_BEGIN_FN("mov_first_1_wide_unrotated");
  128. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  129. CHECK_CALC_END( pjEnd, pEndGlyph );
  130. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 1, ulBufDelta),
  131. (TB, _T("Write into temp buffer off end")));
  132. DC_IGNORE_PARAMETER(cxGlyph);
  133. DC_IGNORE_PARAMETER(RightRot);
  134. while (pGlyph != pjEnd) {
  135. *pBuffer = *pGlyph++;
  136. pBuffer += ulBufDelta;
  137. }
  138. DC_EXIT_POINT:
  139. return;
  140. }
  141. //
  142. //or_all_1_wide_unrotated::
  143. //or_all_1_wide_unrotated_loop::
  144. //
  145. VOID
  146. or_all_1_wide_unrotated(
  147. LONG cyGlyph,
  148. LONG RightRot,
  149. LONG ulBufDelta,
  150. PDCUINT8 pGlyph,
  151. PDCUINT8 pEndGlyph,
  152. PDCUINT8 pBuffer,
  153. PDCUINT8 pEndBuffer,
  154. LONG cxGlyph
  155. )
  156. {
  157. DC_BEGIN_FN("or_all_1_wide_unrotated");
  158. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  159. CHECK_CALC_END( pjEnd, pEndGlyph );
  160. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 1, ulBufDelta),
  161. (TB, _T("Write into temp buffer off end")));
  162. DC_IGNORE_PARAMETER(cxGlyph);
  163. DC_IGNORE_PARAMETER(RightRot);
  164. while (pGlyph != pjEnd) {
  165. *pBuffer |= *pGlyph++;
  166. pBuffer += ulBufDelta;
  167. }
  168. DC_EXIT_POINT:
  169. return;
  170. }
  171. //
  172. // or_first_2_wide_rotated_need_last::
  173. //
  174. VOID
  175. or_first_2_wide_rotated_need_last(
  176. LONG cyGlyph,
  177. LONG RightRot,
  178. LONG ulBufDelta,
  179. PDCUINT8 pGlyph,
  180. PDCUINT8 pEndGlyph,
  181. PDCUINT8 pBuffer,
  182. PDCUINT8 pEndBuffer,
  183. LONG cxGlyph
  184. )
  185. {
  186. DC_BEGIN_FN("or_first_2_wide_rotated_need_last");
  187. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  188. DCUINT32 rl = 8-RightRot;
  189. DCUINT8 c0,c1;
  190. CHECK_CALC_END( pjEnd, pEndGlyph );
  191. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  192. (TB, _T("Write into temp buffer off end")));
  193. DC_IGNORE_PARAMETER(cxGlyph);
  194. while (pGlyph != pjEnd) {
  195. c0 = *pGlyph;
  196. c1 = *(pGlyph+1);
  197. pGlyph+=2;
  198. *pBuffer |= c0 >> RightRot;
  199. *(pBuffer+1) = (DCUINT8)((c1 >> RightRot) | (c0 << rl));
  200. pBuffer += ulBufDelta;
  201. }
  202. DC_EXIT_POINT:
  203. return;
  204. }
  205. //
  206. //or_all_2_wide_rotated_need_last::
  207. //
  208. VOID
  209. or_all_2_wide_rotated_need_last(
  210. LONG cyGlyph,
  211. LONG RightRot,
  212. LONG ulBufDelta,
  213. PDCUINT8 pGlyph,
  214. PDCUINT8 pEndGlyph,
  215. PDCUINT8 pBuffer,
  216. PDCUINT8 pEndBuffer,
  217. LONG cxGlyph
  218. )
  219. {
  220. DC_BEGIN_FN("or_all_2_wide_rotated_need_last");
  221. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  222. DCUINT32 rl = 8-RightRot;
  223. DCUINT16 usTmp;
  224. DCUINT8 c0,c1;
  225. CHECK_CALC_END( pjEnd, pEndGlyph );
  226. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  227. (TB, _T("Write into temp buffer off end")));
  228. DC_IGNORE_PARAMETER(cxGlyph);
  229. while (pGlyph != pjEnd) {
  230. usTmp = *(PDCUINT16)pGlyph;
  231. pGlyph += 2;
  232. c0 = (DCUINT8)usTmp;
  233. c1 = (DCUINT8)(usTmp >> 8);
  234. *pBuffer |= (DCUINT8)(c0 >> RightRot);
  235. *(pBuffer+1) |= (DCUINT8)((c1 >> RightRot) | (c0 << rl));
  236. pBuffer += ulBufDelta;
  237. }
  238. DC_EXIT_POINT:
  239. return;
  240. }
  241. //
  242. // mov_first_2_wide_rotated_need_last::
  243. //
  244. VOID
  245. mov_first_2_wide_rotated_need_last(
  246. LONG cyGlyph,
  247. LONG RightRot,
  248. LONG ulBufDelta,
  249. PDCUINT8 pGlyph,
  250. PDCUINT8 pEndGlyph,
  251. PDCUINT8 pBuffer,
  252. PDCUINT8 pEndBuffer,
  253. LONG cxGlyph
  254. )
  255. {
  256. DC_BEGIN_FN("mov_first_2_wide_rotated_need_last");
  257. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  258. DCUINT32 rl = 8-RightRot;
  259. DCUINT16 us;
  260. DCUINT8 c0;
  261. DCUINT8 c1;
  262. CHECK_CALC_END( pjEnd, pEndGlyph );
  263. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  264. (TB, _T("Write into temp buffer off end")));
  265. DC_IGNORE_PARAMETER(cxGlyph);
  266. while (pGlyph != pjEnd) {
  267. us = *(PDCUINT16)pGlyph;
  268. c0 = (DCUINT8)(us & 0xff);
  269. c1 = (DCUINT8)(us >> 8);
  270. pGlyph += 2;
  271. *pBuffer = (DCUINT8)(c0 >> RightRot);
  272. *(pBuffer+1) = (DCUINT8)((c1 >> RightRot) | (c0 << rl));
  273. pBuffer += ulBufDelta;
  274. }
  275. DC_EXIT_POINT:
  276. return;
  277. }
  278. //
  279. // or_first_2_wide_rotated_no_last
  280. //
  281. VOID
  282. or_first_2_wide_rotated_no_last(
  283. LONG cyGlyph,
  284. LONG RightRot,
  285. LONG ulBufDelta,
  286. PDCUINT8 pGlyph,
  287. PDCUINT8 pEndGlyph,
  288. PDCUINT8 pBuffer,
  289. PDCUINT8 pEndBuffer,
  290. LONG cxGlyph
  291. )
  292. {
  293. DC_BEGIN_FN("or_first_2_wide_rotated_no_last");
  294. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  295. DCUINT32 rl = 8-RightRot;
  296. DCUINT8 c0;
  297. CHECK_CALC_END( pjEnd, pEndGlyph );
  298. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  299. (TB, _T("Write into temp buffer off end")));
  300. DC_IGNORE_PARAMETER(cxGlyph);
  301. while (pGlyph != pjEnd) {
  302. c0 = *pGlyph++;
  303. *pBuffer |= c0 >> RightRot;
  304. *(pBuffer+1) = (DCUINT8)(c0 << rl);
  305. pBuffer += ulBufDelta;
  306. }
  307. DC_EXIT_POINT:
  308. return;
  309. }
  310. //
  311. //or_all_2_wide_rotated_no_last::
  312. //
  313. VOID
  314. or_all_2_wide_rotated_no_last(
  315. LONG cyGlyph,
  316. LONG RightRot,
  317. LONG ulBufDelta,
  318. PDCUINT8 pGlyph,
  319. PDCUINT8 pEndGlyph,
  320. PDCUINT8 pBuffer,
  321. PDCUINT8 pEndBuffer,
  322. LONG cxGlyph
  323. )
  324. {
  325. DC_BEGIN_FN("or_all_2_wide_rotated_no_last");
  326. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  327. DCUINT32 rl = 8-RightRot;
  328. DCUINT8 c;
  329. CHECK_CALC_END( pjEnd, pEndGlyph );
  330. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  331. (TB, _T("Write into temp buffer off end")));
  332. DC_IGNORE_PARAMETER(cxGlyph);
  333. while (pGlyph != pjEnd) {
  334. c = *pGlyph;
  335. pGlyph ++;
  336. *pBuffer |= (DCUINT8)(c >> RightRot);
  337. *(pBuffer+1) |= (DCUINT8)(c << rl);
  338. pBuffer += ulBufDelta;
  339. }
  340. DC_EXIT_POINT:
  341. return;
  342. }
  343. //
  344. // or_all_2_wide_unrotated::
  345. //
  346. VOID
  347. or_all_2_wide_unrotated(
  348. LONG cyGlyph,
  349. LONG RightRot,
  350. LONG ulBufDelta,
  351. PDCUINT8 pGlyph,
  352. PDCUINT8 pEndGlyph,
  353. PDCUINT8 pBuffer,
  354. PDCUINT8 pEndBuffer,
  355. LONG cxGlyph
  356. )
  357. {
  358. DC_BEGIN_FN("or_all_2_wide_unrotated");
  359. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  360. DC_IGNORE_PARAMETER(cxGlyph);
  361. DC_IGNORE_PARAMETER(RightRot);
  362. CHECK_CALC_END( pjEnd, pEndGlyph );
  363. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  364. (TB, _T("Write into temp buffer off end")));
  365. //
  366. // aligned?
  367. //
  368. if ((ULONG_PTR)pBuffer & 0x01) {
  369. //
  370. // not aligned
  371. //
  372. DCUINT16 usTmp;
  373. while (pGlyph != pjEnd) {
  374. usTmp = *(PDCUINT16)pGlyph;
  375. pGlyph +=2;
  376. *pBuffer |= (DCUINT8)usTmp;
  377. *(pBuffer+1) |= (DCUINT8)(usTmp >> 8);
  378. pBuffer += ulBufDelta;
  379. }
  380. } else {
  381. //
  382. // aligned
  383. //
  384. DCUINT16 usTmp;
  385. while (pGlyph != pjEnd) {
  386. usTmp = *(PDCUINT16)pGlyph;
  387. pGlyph +=2;
  388. *(PDCUINT16)pBuffer |= usTmp;
  389. pBuffer += ulBufDelta;
  390. }
  391. }
  392. DC_EXIT_POINT:
  393. return;
  394. }
  395. //
  396. // mov_first_2_wide_unrotated::
  397. //
  398. VOID
  399. mov_first_2_wide_unrotated(
  400. LONG cyGlyph,
  401. LONG RightRot,
  402. LONG ulBufDelta,
  403. PDCUINT8 pGlyph,
  404. PDCUINT8 pEndGlyph,
  405. PDCUINT8 pBuffer,
  406. PDCUINT8 pEndBuffer,
  407. LONG cxGlyph
  408. )
  409. {
  410. DC_BEGIN_FN("mov_first_2_wide_unrotated");
  411. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  412. DCUINT16 us;
  413. CHECK_CALC_END( pjEnd, pEndGlyph );
  414. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  415. (TB, _T("Write into temp buffer off end")));
  416. DC_IGNORE_PARAMETER(cxGlyph);
  417. DC_IGNORE_PARAMETER(RightRot);
  418. while (pGlyph != pjEnd) {
  419. us = *(PDCUINT16)pGlyph;
  420. pGlyph +=2;
  421. *pBuffer = (DCUINT8)(us & 0xff);
  422. *(pBuffer+1) = (DCUINT8)(us >> 8);
  423. pBuffer += ulBufDelta;
  424. }
  425. DC_EXIT_POINT:
  426. return;
  427. }
  428. //
  429. // mov_first_2_wide_rotated_no_last::
  430. //
  431. VOID
  432. mov_first_2_wide_rotated_no_last(
  433. LONG cyGlyph,
  434. LONG RightRot,
  435. LONG ulBufDelta,
  436. PDCUINT8 pGlyph,
  437. PDCUINT8 pEndGlyph,
  438. PDCUINT8 pBuffer,
  439. PDCUINT8 pEndBuffer,
  440. LONG cxGlyph
  441. )
  442. {
  443. DC_BEGIN_FN("mov_first_2_wide_rotated_no_last");
  444. PDCUINT8 pjEnd = pGlyph + cyGlyph;
  445. DCUINT32 rl = 8-RightRot;
  446. DCUINT8 c0;
  447. CHECK_CALC_END( pjEnd, pEndGlyph );
  448. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 2, ulBufDelta),
  449. (TB, _T("Write into temp buffer off end")));
  450. DC_IGNORE_PARAMETER(cxGlyph);
  451. while (pGlyph != pjEnd) {
  452. c0 = *pGlyph++;
  453. *pBuffer = (DCUINT8)(c0 >> RightRot);
  454. *(pBuffer+1) = (DCUINT8)(c0 << rl);
  455. pBuffer += ulBufDelta;
  456. }
  457. DC_EXIT_POINT:
  458. return;
  459. }
  460. //
  461. // or_first_3_wide_rotated_need_last::
  462. //
  463. VOID
  464. or_first_3_wide_rotated_need_last(
  465. LONG cyGlyph,
  466. LONG RightRot,
  467. LONG ulBufDelta,
  468. PDCUINT8 pGlyph,
  469. PDCUINT8 pEndGlyph,
  470. PDCUINT8 pBuffer,
  471. PDCUINT8 pEndBuffer,
  472. LONG cxGlyph
  473. )
  474. {
  475. DC_BEGIN_FN("or_first_3_wide_rotated_need_last");
  476. PDCUINT8 pjEnd = pGlyph + 3*cyGlyph;
  477. DCUINT32 ul;
  478. DCUINT8 c0,c1,c2;
  479. CHECK_CALC_END( pjEnd, pEndGlyph );
  480. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 3, ulBufDelta),
  481. (TB, _T("Write into temp buffer off end")));
  482. DC_IGNORE_PARAMETER(cxGlyph);
  483. while (pGlyph != pjEnd) {
  484. c0 = *pGlyph;
  485. c1 = *(pGlyph+1);
  486. c2 = *(pGlyph+2);
  487. //
  488. // make into big-endian DCUINT32 and shift
  489. //
  490. ul = ((DCUINT32)c0 << 16) | ((DCUINT32)c1 << 8) | c2;
  491. ul >>= RightRot;
  492. *pBuffer |= (BYTE)(ul >> 16);
  493. *(pBuffer+1) = (BYTE)(ul >> 8);
  494. *(pBuffer+2) = (BYTE)(ul);
  495. pGlyph += 3;
  496. pBuffer += ulBufDelta;
  497. }
  498. DC_EXIT_POINT:
  499. return;
  500. }
  501. //
  502. // or_all_3_wide_rotated_need_last::
  503. //
  504. VOID
  505. or_all_3_wide_rotated_need_last(
  506. LONG cyGlyph,
  507. LONG RightRot,
  508. LONG ulBufDelta,
  509. PDCUINT8 pGlyph,
  510. PDCUINT8 pEndGlyph,
  511. PDCUINT8 pBuffer,
  512. PDCUINT8 pEndBuffer,
  513. LONG cxGlyph
  514. )
  515. {
  516. DC_BEGIN_FN("or_all_3_wide_rotated_need_last");
  517. PDCUINT8 pjEnd = pGlyph + 3*cyGlyph;
  518. DCUINT32 ul;
  519. DCUINT8 c0,c1,c2;
  520. CHECK_CALC_END( pjEnd, pEndGlyph );
  521. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 3, ulBufDelta),
  522. (TB, _T("Write into temp buffer off end")));
  523. DC_IGNORE_PARAMETER(cxGlyph);
  524. while (pGlyph != pjEnd) {
  525. c0 = *pGlyph;
  526. c1 = *(pGlyph+1);
  527. c2 = *(pGlyph+2);
  528. //
  529. // make into big-endian DCUINT32 and shift
  530. //
  531. ul = ((DCUINT32)c0 << 16) | ((DCUINT32)c1 << 8) | c2;
  532. ul >>= RightRot;
  533. *pBuffer |= (BYTE)(ul >> 16);
  534. *(pBuffer+1) |= (BYTE)(ul >> 8);
  535. *(pBuffer+2) |= (BYTE)(ul);
  536. pGlyph += 3;
  537. pBuffer += ulBufDelta;
  538. }
  539. DC_EXIT_POINT:
  540. return;
  541. }
  542. //
  543. // or_all_3_wide_rotated_no_last::
  544. //
  545. VOID
  546. or_all_3_wide_rotated_no_last(
  547. LONG cyGlyph,
  548. LONG RightRot,
  549. LONG ulBufDelta,
  550. PDCUINT8 pGlyph,
  551. PDCUINT8 pEndGlyph,
  552. PDCUINT8 pBuffer,
  553. PDCUINT8 pEndBuffer,
  554. LONG cxGlyph
  555. )
  556. {
  557. DC_BEGIN_FN("or_all_3_wide_rotated_no_last");
  558. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  559. DCUINT32 ul;
  560. DCUINT8 c0,c1;
  561. CHECK_CALC_END( pjEnd, pEndGlyph );
  562. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 3, ulBufDelta),
  563. (TB, _T("Write into temp buffer off end")));
  564. DC_IGNORE_PARAMETER(cxGlyph);
  565. while (pGlyph != pjEnd) {
  566. c0 = *pGlyph;
  567. c1 = *(pGlyph+1);
  568. //
  569. // make big-endian and shift
  570. //
  571. ul = ((DCUINT32)c0 << 16) | ((DCUINT32)c1 << 8);
  572. ul >>= RightRot;
  573. //
  574. // store result
  575. //
  576. *pBuffer |= (BYTE)(ul >> 16);
  577. *(pBuffer+1) |= (BYTE)(ul >> 8);
  578. *(pBuffer+2) |= (BYTE)ul;
  579. pGlyph += 2;
  580. pBuffer += ulBufDelta;
  581. }
  582. DC_EXIT_POINT:
  583. return;
  584. }
  585. //
  586. // or_first_3_wide_rotated_no_last::
  587. //
  588. VOID
  589. or_first_3_wide_rotated_no_last(
  590. LONG cyGlyph,
  591. LONG RightRot,
  592. LONG ulBufDelta,
  593. PDCUINT8 pGlyph,
  594. PDCUINT8 pEndGlyph,
  595. PDCUINT8 pBuffer,
  596. PDCUINT8 pEndBuffer,
  597. LONG cxGlyph
  598. )
  599. {
  600. DC_BEGIN_FN("or_first_3_wide_rotated_no_last");
  601. PDCUINT8 pjEnd = pGlyph + 2*cyGlyph;
  602. DCUINT32 ul;
  603. DCUINT8 c0,c1;
  604. CHECK_CALC_END( pjEnd, pEndGlyph );
  605. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 3, ulBufDelta),
  606. (TB, _T("Write into temp buffer off end")));
  607. DC_IGNORE_PARAMETER(cxGlyph);
  608. while (pGlyph != pjEnd) {
  609. c0 = *pGlyph;
  610. c1 = *(pGlyph+1);
  611. //
  612. // make big-endian and shift
  613. //
  614. ul = ((DCUINT32)c0 << 16) | ((DCUINT32)c1 << 8);
  615. ul >>= RightRot;
  616. //
  617. // store result, only or in first byte
  618. //
  619. *pBuffer |= (BYTE)(ul >> 16);
  620. *(pBuffer+1) = (BYTE)(ul >> 8);
  621. *(pBuffer+2) = (BYTE)ul;
  622. pGlyph += 2;
  623. pBuffer += ulBufDelta;
  624. }
  625. DC_EXIT_POINT:
  626. return;
  627. }
  628. //
  629. // mov_first_3_wide_unrotated::
  630. //
  631. VOID
  632. mov_first_3_wide_unrotated(
  633. LONG cyGlyph,
  634. LONG RightRot,
  635. LONG ulBufDelta,
  636. PDCUINT8 pGlyph,
  637. PDCUINT8 pEndGlyph,
  638. PDCUINT8 pBuffer,
  639. PDCUINT8 pEndBuffer,
  640. LONG cxGlyph
  641. )
  642. {
  643. DC_BEGIN_FN("mov_first_3_wide_unrotated");
  644. PDCUINT8 pjEnd = pGlyph + 3*cyGlyph;
  645. DCUINT32 rl = 8-RightRot;
  646. DCUINT8 c0,c1,c2;
  647. CHECK_CALC_END( pjEnd, pEndGlyph );
  648. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 3, ulBufDelta),
  649. (TB, _T("Write into temp buffer off end")));
  650. DC_IGNORE_PARAMETER(cxGlyph);
  651. while (pGlyph != pjEnd) {
  652. c0 = *pGlyph;
  653. c1 = *(pGlyph+1);
  654. c2 = *(pGlyph+2);
  655. *pBuffer = c0;
  656. *(pBuffer+1) = c1;
  657. *(pBuffer+2) = c2;
  658. pGlyph += 3;
  659. pBuffer += ulBufDelta;
  660. }
  661. DC_EXIT_POINT:
  662. return;
  663. }
  664. //
  665. //or_all_3_wide_unrotated::
  666. //
  667. VOID
  668. or_all_3_wide_unrotated(
  669. LONG cyGlyph,
  670. LONG RightRot,
  671. LONG ulBufDelta,
  672. PDCUINT8 pGlyph,
  673. PDCUINT8 pEndGlyph,
  674. PDCUINT8 pBuffer,
  675. PDCUINT8 pEndBuffer,
  676. LONG cxGlyph
  677. )
  678. {
  679. DC_BEGIN_FN("or_all_3_wide_unrotated");
  680. PDCUINT8 pjEnd = pGlyph + 3*cyGlyph;
  681. DCUINT32 rl = 8-RightRot;
  682. DCUINT8 c0,c1,c2;
  683. CHECK_CALC_END( pjEnd, pEndGlyph );
  684. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 3, ulBufDelta),
  685. (TB, _T("Write into temp buffer off end")));
  686. DC_IGNORE_PARAMETER(cxGlyph);
  687. while (pGlyph != pjEnd) {
  688. c0 = *pGlyph;
  689. c1 = *(pGlyph+1);
  690. c2 = *(pGlyph+2);
  691. *pBuffer |= c0;
  692. *(pBuffer+1) |= c1;
  693. *(pBuffer+2) |= c2;
  694. pBuffer += ulBufDelta;
  695. pGlyph += 3;
  696. }
  697. DC_EXIT_POINT:
  698. return;
  699. }
  700. //
  701. // or_first_4_wide_rotated_need_last::
  702. //
  703. VOID
  704. or_first_4_wide_rotated_need_last(
  705. LONG cyGlyph,
  706. LONG RightRot,
  707. LONG ulBufDelta,
  708. PDCUINT8 pGlyph,
  709. PDCUINT8 pEndGlyph,
  710. PDCUINT8 pBuffer,
  711. PDCUINT8 pEndBuffer,
  712. LONG cxGlyph
  713. )
  714. {
  715. DC_BEGIN_FN("or_first_4_wide_rotated_need_last");
  716. PDCUINT8 pjEnd = pGlyph + 4*cyGlyph;
  717. DCUINT32 ul;
  718. DCUINT32 t0,t1,t2;
  719. CHECK_CALC_END( pjEnd, pEndGlyph );
  720. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 4, ulBufDelta),
  721. (TB, _T("Write into temp buffer off end")));
  722. DC_IGNORE_PARAMETER(cxGlyph);
  723. while (pGlyph != pjEnd) {
  724. ul = *(PDCUINT32)pGlyph;
  725. //
  726. // endian swap
  727. //
  728. t0 = ul << 24;
  729. t1 = ul >> 24;
  730. t2 = (ul >> 8) & 0x00ff00;
  731. ul = (ul << 8) & 0xff0000;
  732. ul = ul | t0 | t1 | t2;
  733. ul >>= RightRot;
  734. *pBuffer |= (BYTE)(ul >> 24);
  735. *(pBuffer+1) = (BYTE)(ul >> 16);
  736. *(pBuffer+2) = (BYTE)(ul >> 8);
  737. *(pBuffer+3) = (BYTE)(ul);
  738. pGlyph += 4;
  739. pBuffer += ulBufDelta;
  740. }
  741. DC_EXIT_POINT:
  742. return;
  743. }
  744. //
  745. // or_all_4_wide_rotated_need_last::
  746. //
  747. VOID
  748. or_all_4_wide_rotated_need_last(
  749. LONG cyGlyph,
  750. LONG RightRot,
  751. LONG ulBufDelta,
  752. PDCUINT8 pGlyph,
  753. PDCUINT8 pEndGlyph,
  754. PDCUINT8 pBuffer,
  755. PDCUINT8 pEndBuffer,
  756. LONG cxGlyph
  757. )
  758. {
  759. DC_BEGIN_FN("or_all_4_wide_rotated_need_last");
  760. PDCUINT8 pjEnd = pGlyph + 4*cyGlyph;
  761. DCUINT32 ul;
  762. DCUINT32 t0,t1,t2;
  763. CHECK_CALC_END( pjEnd, pEndGlyph );
  764. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 4, ulBufDelta),
  765. (TB, _T("Write into temp buffer off end")));
  766. DC_IGNORE_PARAMETER(cxGlyph);
  767. while (pGlyph != pjEnd) {
  768. ul = *(PDCUINT32)pGlyph;
  769. //
  770. // endian swap
  771. //
  772. t0 = ul << 24;
  773. t1 = ul >> 24;
  774. t2 = (ul >> 8) & 0x00ff00;
  775. ul = (ul << 8) & 0xff0000;
  776. ul = ul | t0 | t1 | t2;
  777. ul >>= RightRot;
  778. *pBuffer |= (BYTE)(ul >> 24);
  779. *(pBuffer+1) |= (BYTE)(ul >> 16);
  780. *(pBuffer+2) |= (BYTE)(ul >> 8);
  781. *(pBuffer+3) |= (BYTE)(ul);
  782. pGlyph += 4;
  783. pBuffer += ulBufDelta;
  784. }
  785. DC_EXIT_POINT:
  786. return;
  787. }
  788. //
  789. // or_first_4_wide_rotated_no_last::
  790. //
  791. VOID
  792. or_first_4_wide_rotated_no_last(
  793. LONG cyGlyph,
  794. LONG RightRot,
  795. LONG ulBufDelta,
  796. PDCUINT8 pGlyph,
  797. PDCUINT8 pEndGlyph,
  798. PDCUINT8 pBuffer,
  799. PDCUINT8 pEndBuffer,
  800. LONG cxGlyph
  801. )
  802. {
  803. DC_BEGIN_FN("or_first_4_wide_rotated_no_last");
  804. PDCUINT8 pjEnd = pGlyph + 3*cyGlyph;
  805. BYTE c0,c1,c2;
  806. DCUINT32 ul;
  807. CHECK_CALC_END( pjEnd, pEndGlyph );
  808. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 4, ulBufDelta),
  809. (TB, _T("Write into temp buffer off end")));
  810. DC_IGNORE_PARAMETER(cxGlyph);
  811. while (pGlyph != pjEnd) {
  812. //
  813. // load src
  814. //
  815. c0 = *pGlyph;
  816. c1 = *(pGlyph+1);
  817. c2 = *(pGlyph+2);
  818. //
  819. // or into big endian DCUINT32 and shift
  820. //
  821. ul = ((DCUINT32)c0 << 24) | ((DCUINT32)c1 << 16) | ((DCUINT32)c2 << 8);
  822. ul >>= RightRot;
  823. //
  824. // store result, ony or in fisrt byte
  825. //
  826. *pBuffer |= (BYTE)(ul >> 24);
  827. *(pBuffer+1) = (BYTE)(ul >> 16);;
  828. *(pBuffer+2) = (BYTE)(ul >> 8);
  829. *(pBuffer+3) = (BYTE)(ul);
  830. //
  831. // inc scan line
  832. //
  833. pGlyph += 3;
  834. pBuffer += ulBufDelta;
  835. }
  836. DC_EXIT_POINT:
  837. return;
  838. }
  839. //
  840. // or_all_4_wide_rotated_no_last::
  841. //
  842. VOID
  843. or_all_4_wide_rotated_no_last(
  844. LONG cyGlyph,
  845. LONG RightRot,
  846. LONG ulBufDelta,
  847. PDCUINT8 pGlyph,
  848. PDCUINT8 pEndGlyph,
  849. PDCUINT8 pBuffer,
  850. PDCUINT8 pEndBuffer,
  851. LONG cxGlyph
  852. )
  853. {
  854. DC_BEGIN_FN("or_all_4_wide_rotated_no_last");
  855. PDCUINT8 pjEnd = pGlyph + 3*cyGlyph;
  856. BYTE c0,c1,c2;
  857. DCUINT32 ul;
  858. CHECK_CALC_END( pjEnd, pEndGlyph );
  859. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 4, ulBufDelta),
  860. (TB, _T("Write into temp buffer off end")));
  861. DC_IGNORE_PARAMETER(cxGlyph);
  862. while (pGlyph != pjEnd) {
  863. //
  864. // load src
  865. //
  866. c0 = *pGlyph;
  867. c1 = *(pGlyph+1);
  868. c2 = *(pGlyph+2);
  869. //
  870. // or into big endian DCUINT32 and shift
  871. //
  872. ul = ((DCUINT32)c0 << 24) | ((DCUINT32)c1 << 16) | ((DCUINT32)c2 << 8);
  873. ul >>= RightRot;
  874. //
  875. // store result
  876. //
  877. *pBuffer |= (BYTE)(ul >> 24);
  878. *(pBuffer+1) |= (BYTE)(ul >> 16);;
  879. *(pBuffer+2) |= (BYTE)(ul >> 8);
  880. *(pBuffer+3) |= (BYTE)(ul);
  881. //
  882. // inc scan line
  883. //
  884. pGlyph += 3;
  885. pBuffer += ulBufDelta;
  886. }
  887. DC_EXIT_POINT:
  888. return;
  889. }
  890. VOID
  891. mov_first_4_wide_unrotated(
  892. LONG cyGlyph,
  893. LONG RightRot,
  894. LONG ulBufDelta,
  895. PDCUINT8 pGlyph,
  896. PDCUINT8 pEndGlyph,
  897. PDCUINT8 pBuffer,
  898. PDCUINT8 pEndBuffer,
  899. LONG cxGlyph
  900. )
  901. {
  902. DC_BEGIN_FN("mov_first_4_wide_unrotated");
  903. PDCUINT8 pjEnd = pGlyph + 4*cyGlyph;
  904. CHECK_CALC_END( pjEnd, pEndGlyph );
  905. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 4, ulBufDelta),
  906. (TB, _T("Write into temp buffer off end")));
  907. DC_IGNORE_PARAMETER(cxGlyph);
  908. DC_IGNORE_PARAMETER(RightRot);
  909. switch ((ULONG_PTR)pBuffer & 0x03 ) {
  910. case 0:
  911. while (pGlyph != pjEnd) {
  912. *(PDCUINT32)pBuffer = *(PDCUINT32)pGlyph;
  913. pGlyph += 4;
  914. pBuffer += ulBufDelta;
  915. }
  916. break;
  917. case 1:
  918. case 3:
  919. while (pGlyph != pjEnd) {
  920. *pBuffer = *pGlyph;
  921. *(pBuffer+1) = *(pGlyph+1);
  922. *(pBuffer+2) = *(pGlyph+2);
  923. *(pBuffer+3) = *(pGlyph+3);
  924. pGlyph += 4;
  925. pBuffer += ulBufDelta;
  926. }
  927. break;
  928. case 2:
  929. while (pGlyph != pjEnd) {
  930. *(PDCUINT16)(pBuffer) = *(PDCUINT16)pGlyph;
  931. *(PDCUINT16)(pBuffer+2) = *(PDCUINT16)(pGlyph+2);
  932. pBuffer += ulBufDelta;
  933. pGlyph += 4;
  934. }
  935. break;
  936. }
  937. DC_EXIT_POINT:
  938. return;
  939. }
  940. //
  941. // or_all_4_wide_unrotated::
  942. //
  943. VOID
  944. or_all_4_wide_unrotated(
  945. LONG cyGlyph,
  946. LONG RightRot,
  947. LONG ulBufDelta,
  948. PDCUINT8 pGlyph,
  949. PDCUINT8 pEndGlyph,
  950. PDCUINT8 pBuffer,
  951. PDCUINT8 pEndBuffer,
  952. LONG cxGlyph
  953. )
  954. {
  955. DC_BEGIN_FN("or_all_4_wide_unrotated");
  956. PDCUINT8 pjEnd = pGlyph + 4*cyGlyph;
  957. CHECK_CALC_END( pjEnd, pEndGlyph );
  958. CHECK_WRITE_N_BYTES_NO_HR(pBuffer, pEndBuffer, CALC_WRITE_SIZE(cyGlyph, 4, ulBufDelta),
  959. (TB, _T("Write into temp buffer off end")));
  960. DC_IGNORE_PARAMETER(cxGlyph);
  961. DC_IGNORE_PARAMETER(RightRot);
  962. switch ((ULONG_PTR)pBuffer & 0x03 ) {
  963. case 0:
  964. while (pGlyph != pjEnd) {
  965. *(PDCUINT32)pBuffer |= *(PDCUINT32)pGlyph;
  966. pGlyph += 4;
  967. pBuffer += ulBufDelta;
  968. }
  969. break;
  970. case 1:
  971. case 3:
  972. while (pGlyph != pjEnd) {
  973. *pBuffer |= *pGlyph;
  974. *(pBuffer+1) |= *(pGlyph+1);
  975. *(pBuffer+2) |= *(pGlyph+2);
  976. *(pBuffer+3) |= *(pGlyph+3);
  977. pGlyph += 4;
  978. pBuffer += ulBufDelta;
  979. }
  980. break;
  981. case 2:
  982. while (pGlyph != pjEnd) {
  983. *(PDCUINT16)pBuffer |= *(PDCUINT16)pGlyph;
  984. *(PDCUINT16)(pBuffer+2) |= *(PDCUINT16)(pGlyph+2);
  985. pGlyph += 4;
  986. pBuffer += ulBufDelta;
  987. }
  988. break;
  989. }
  990. DC_EXIT_POINT:
  991. return;
  992. }
  993. /******************************Public*Routine******************************\
  994. *
  995. * Routine Name
  996. *
  997. * or_first_N_wide_rotated_need_last
  998. *
  999. *
  1000. * Routine Description:
  1001. *
  1002. * Draw arbitrarily wide glyphs to 1BPP temp buffer
  1003. *
  1004. *
  1005. * Arguments:
  1006. *
  1007. * cyGlyph - glyph height
  1008. * RightRot - alignment
  1009. * ulBufDelta - scan line stride of temp buffer
  1010. * pGlyph - pointer to glyph bitmap
  1011. * pBuffer - pointer to temp buffer
  1012. * cxGlyph - glyph width in pixels
  1013. * cxDst - Dest width in bytes
  1014. *
  1015. * Return Value:
  1016. *
  1017. * None
  1018. *
  1019. \**************************************************************************/
  1020. VOID
  1021. or_first_N_wide_rotated_need_last(
  1022. LONG cyGlyph,
  1023. LONG RightRot,
  1024. LONG ulBufDelta,
  1025. PDCUINT8 pGlyph,
  1026. PDCUINT8 pEndGlyph,
  1027. PDCUINT8 pBuffer,
  1028. PDCUINT8 pEndBuffer,
  1029. LONG cxGlyph,
  1030. LONG cxDst
  1031. )
  1032. {
  1033. DC_BEGIN_FN("or_first_N_wide_rotated_need_last");
  1034. PDCUINT8 pjDst = (PDCUINT8)pBuffer;
  1035. PDCUINT8 pjDstEnd;
  1036. PDCUINT8 pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1037. LONG lStride = ulBufDelta - cxDst;
  1038. LONG rl = 8-RightRot;
  1039. DC_IGNORE_PARAMETER(cxGlyph);
  1040. //
  1041. // source doesn't advance after first byte, and
  1042. // we do the first byte outside the loop
  1043. //
  1044. while (pjDst != pjDstEndy) {
  1045. CHECK_READ_N_BYTES_NO_HR(pGlyph, pEndGlyph, 1 + cxDst,
  1046. (TB, _T("Read off the end of glyph data")));
  1047. CHECK_WRITE_ONE_BYTE_NO_HR(pjDst, pEndBuffer,
  1048. (TB, _T("Write off the end of glyph data")));
  1049. DCUINT8 c0 = *pGlyph++;
  1050. DCUINT8 c1;
  1051. pjDstEnd = pjDst + cxDst;
  1052. *pjDst |= c0 >> RightRot;
  1053. pjDst++;
  1054. c1 = (DCUINT8)(c0 << rl);
  1055. CHECK_CALC_END( pjDstEnd, pEndBuffer );
  1056. //
  1057. // know cxDst is at least 4, use do-while
  1058. //
  1059. while (pjDst != pjDstEnd) {
  1060. c0 = *pGlyph;
  1061. *pjDst = (DCUINT8)((c0 >> RightRot) | c1);
  1062. c1 = (DCUINT8)(c0 << rl);
  1063. pjDst++;
  1064. pGlyph++;
  1065. }
  1066. pjDst += lStride;
  1067. }
  1068. DC_EXIT_POINT:
  1069. return;
  1070. }
  1071. VOID
  1072. or_all_N_wide_rotated_need_last(
  1073. LONG cyGlyph,
  1074. LONG RightRot,
  1075. LONG ulBufDelta,
  1076. PDCUINT8 pGlyph,
  1077. PDCUINT8 pEndGlyph,
  1078. PDCUINT8 pBuffer,
  1079. PDCUINT8 pEndBuffer,
  1080. LONG cxGlyph,
  1081. LONG cxDst
  1082. )
  1083. {
  1084. DC_BEGIN_FN("or_all_N_wide_rotated_need_last");
  1085. PDCUINT8 pjDst = (PDCUINT8)pBuffer;
  1086. PDCUINT8 pjDstEnd;
  1087. PDCUINT8 pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1088. LONG lStride = ulBufDelta - cxDst;
  1089. LONG rl = 8-RightRot;
  1090. DC_IGNORE_PARAMETER(cxGlyph);
  1091. //
  1092. // source doesn't advance after first byte, and
  1093. // we do the first byte outside the loop
  1094. //
  1095. while (pjDst != pjDstEndy) {
  1096. CHECK_READ_N_BYTES_NO_HR(pGlyph, pEndGlyph, 1 + cxDst,
  1097. (TB, _T("Read off the end of glyph data")));
  1098. DCUINT8 c0 = *pGlyph++;
  1099. DCUINT8 c1;
  1100. pjDstEnd = pjDst + cxDst;
  1101. CHECK_WRITE_ONE_BYTE_NO_HR(pjDst, pEndBuffer,
  1102. (TB, _T("Write off the end of glyph data")));
  1103. *pjDst |= c0 >> RightRot;
  1104. pjDst++;
  1105. c1 = (DCUINT8)(c0 << rl);
  1106. //
  1107. // know cxDst is at least 4, use do-while
  1108. //
  1109. CHECK_CALC_END( pjDstEnd, pEndBuffer );
  1110. while (pjDst != pjDstEnd) {
  1111. c0 = *pGlyph;
  1112. *pjDst |= ((c0 >> RightRot) | c1);
  1113. c1 = (DCUINT8)(c0 << rl);
  1114. pjDst++;
  1115. pGlyph++;
  1116. }
  1117. pjDst += lStride;
  1118. }
  1119. DC_EXIT_POINT:
  1120. return;
  1121. }
  1122. VOID
  1123. or_first_N_wide_rotated_no_last(
  1124. LONG cyGlyph,
  1125. LONG RightRot,
  1126. LONG ulBufDelta,
  1127. PDCUINT8 pGlyph,
  1128. PDCUINT8 pEndGlyph,
  1129. PDCUINT8 pBuffer,
  1130. PDCUINT8 pEndBuffer,
  1131. LONG cxGlyph,
  1132. LONG cxDst
  1133. )
  1134. {
  1135. DC_BEGIN_FN("or_first_N_wide_rotated_no_last");
  1136. PDCUINT8 pjDst = (PDCUINT8)pBuffer;
  1137. PDCUINT8 pjDstEnd;
  1138. PDCUINT8 pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1139. LONG lStride = ulBufDelta - cxDst;
  1140. LONG rl = 8-RightRot;
  1141. DC_IGNORE_PARAMETER(cxGlyph);
  1142. //
  1143. // source doesn't advance after first byte, and
  1144. // we do the first byte outside the loop
  1145. //
  1146. while (pjDst != pjDstEndy) {
  1147. DCUINT8 c0;
  1148. DCUINT8 c1;
  1149. pjDstEnd = pjDst + cxDst - 1;
  1150. CHECK_READ_N_BYTES_NO_HR(pGlyph, pEndGlyph, 1 + cxDst,
  1151. (TB, _T("Read off the end of glyph data")));
  1152. CHECK_WRITE_ONE_BYTE_NO_HR(pjDst, pEndBuffer,
  1153. (TB, _T("Write off the end of glyph data")));
  1154. //
  1155. // do first dest byte outside loop for OR
  1156. //
  1157. c1 = 0;
  1158. c0 = *pGlyph;
  1159. *pjDst |= ((c0 >> RightRot) | c1);
  1160. pjDst++;
  1161. pGlyph++;
  1162. //
  1163. // know cxDst is at least 4, use do-while
  1164. //
  1165. CHECK_CALC_END( pjDstEnd + 1, pEndBuffer );
  1166. while (pjDst != pjDstEnd) {
  1167. c0 = *pGlyph;
  1168. *pjDst = (DCUINT8)((c0 >> RightRot) | c1);
  1169. c1 = (DCUINT8)(c0 << rl);
  1170. pjDst++;
  1171. pGlyph++;
  1172. }
  1173. //
  1174. // last dst byte outside loop, no new src needed
  1175. //
  1176. *pjDst = c1;
  1177. pjDst++;
  1178. pjDst += lStride;
  1179. }
  1180. DC_EXIT_POINT:
  1181. return;
  1182. }
  1183. VOID
  1184. or_all_N_wide_rotated_no_last(
  1185. LONG cyGlyph,
  1186. LONG RightRot,
  1187. LONG ulBufDelta,
  1188. PDCUINT8 pGlyph,
  1189. PDCUINT8 pEndGlyph,
  1190. PDCUINT8 pBuffer,
  1191. PDCUINT8 pEndBuffer,
  1192. LONG cxGlyph,
  1193. LONG cxDst
  1194. )
  1195. {
  1196. DC_BEGIN_FN("or_all_N_wide_rotated_no_last");
  1197. PDCUINT8 pjDst = (PDCUINT8)pBuffer;
  1198. PDCUINT8 pjDstEnd;
  1199. PDCUINT8 pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1200. LONG lStride = ulBufDelta - cxDst;
  1201. LONG rl = 8-RightRot;
  1202. DC_IGNORE_PARAMETER(cxGlyph);
  1203. //
  1204. // source doesn't advance after first byte, and
  1205. // we do the first byte outside the loop
  1206. //
  1207. while (pjDst != pjDstEndy) {
  1208. DCUINT8 c0;
  1209. DCUINT8 c1;
  1210. pjDstEnd = pjDst + cxDst - 1;
  1211. CHECK_READ_N_BYTES_NO_HR(pGlyph, pEndGlyph, 1 + cxDst,
  1212. (TB, _T("Read off the end of glyph data")));
  1213. //
  1214. // do first dest byte outside loop for OR
  1215. //
  1216. c1 = 0;
  1217. //
  1218. // know cxDst is at least 4, use do-while
  1219. //
  1220. CHECK_CALC_END( pjDstEnd + 1, pEndBuffer );
  1221. while (pjDst != pjDstEnd) {
  1222. c0 = *pGlyph;
  1223. *pjDst |= ((c0 >> RightRot) | c1);
  1224. c1 = (DCUINT8)(c0 << rl);
  1225. pjDst++;
  1226. pGlyph++;
  1227. }
  1228. //
  1229. // last dst byte outside loop, no new src needed
  1230. //
  1231. *pjDst |= c1;
  1232. pjDst++;
  1233. pjDst += lStride;
  1234. }
  1235. DC_EXIT_POINT:
  1236. return;
  1237. }
  1238. //
  1239. // The following routines can be significantly sped up by
  1240. // breaking them out into DWORD alignment cases.
  1241. //
  1242. VOID
  1243. mov_first_N_wide_unrotated(
  1244. LONG cyGlyph,
  1245. LONG RightRot,
  1246. LONG ulBufDelta,
  1247. PDCUINT8 pGlyph,
  1248. PDCUINT8 pEndGlyph,
  1249. PDCUINT8 pBuffer,
  1250. PDCUINT8 pEndBuffer,
  1251. LONG cxGlyph,
  1252. LONG cxDst
  1253. )
  1254. {
  1255. DC_BEGIN_FN("mov_first_N_wide_unrotated");
  1256. PDCUINT8 pjDst = (PDCUINT8)pBuffer;
  1257. PDCUINT8 pjDstEnd;
  1258. PDCUINT8 pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1259. LONG lStride = ulBufDelta - cxDst;
  1260. DC_IGNORE_PARAMETER(cxGlyph);
  1261. DC_IGNORE_PARAMETER(RightRot);
  1262. // SECURITY: cyGlyph reads in the outerloop + cxDst reads in cyGlyph reps of the
  1263. // inner loop
  1264. CHECK_READ_N_BYTES_NO_HR(pGlyph, pEndGlyph, cyGlyph * cxDst,
  1265. (TB, _T("Read off the end of glyph data")));
  1266. //
  1267. // byte aligned copy
  1268. //
  1269. while (pjDst != pjDstEndy) {
  1270. pjDstEnd = pjDst + cxDst;
  1271. //
  1272. // let compiler unroll inner loop
  1273. //
  1274. CHECK_CALC_END( pjDstEnd, pEndBuffer );
  1275. while (pjDst != pjDstEnd ) {
  1276. *pjDst++ = *pGlyph++;
  1277. }
  1278. pjDst += lStride;
  1279. }
  1280. DC_EXIT_POINT:
  1281. return;
  1282. }
  1283. VOID
  1284. or_all_N_wide_unrotated(
  1285. LONG cyGlyph,
  1286. LONG RightRot,
  1287. LONG ulBufDelta,
  1288. PDCUINT8 pGlyph,
  1289. PDCUINT8 pEndGlyph,
  1290. PDCUINT8 pBuffer,
  1291. PDCUINT8 pEndBuffer,
  1292. LONG cxGlyph,
  1293. LONG cxDst
  1294. )
  1295. {
  1296. DC_BEGIN_FN("or_all_N_wide_unrotated");
  1297. PDCUINT8 pjDst = (PDCUINT8)pBuffer;
  1298. PDCUINT8 pjDstEnd;
  1299. PDCUINT8 pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1300. LONG lStride = ulBufDelta - cxDst;
  1301. DC_IGNORE_PARAMETER(cxGlyph);
  1302. DC_IGNORE_PARAMETER(RightRot);
  1303. // SECURITY: cyGlyph reads in the outerloop + cxDst reads in cyGlyph reps of the
  1304. // inner loop
  1305. CHECK_READ_N_BYTES_NO_HR(pGlyph, pEndGlyph, cyGlyph * cxDst,
  1306. (TB, _T("Read off the end of glyph data")));
  1307. //
  1308. // byte aligned copy
  1309. //
  1310. while (pjDst != pjDstEndy) {
  1311. pjDstEnd = pjDst + cxDst;
  1312. //
  1313. // let compiler unroll inner loop
  1314. //
  1315. CHECK_CALC_END( pjDstEnd, pEndBuffer );
  1316. while (pjDst != pjDstEnd ) {
  1317. *pjDst++ |= *pGlyph++;
  1318. }
  1319. pjDst += lStride;
  1320. }
  1321. DC_EXIT_POINT:
  1322. return;
  1323. }