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.

1985 lines
45 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: textxl.c
  3. *
  4. * Draw glyphs to 1Bpp temporary buffer. This is the portable version
  5. * of the x86 code from the VGA driver.
  6. *
  7. *
  8. * Copyright (c) 1994-1999 Microsoft Corporation
  9. \**************************************************************************/
  10. #include "engine.h"
  11. #if !defined (_X86_)
  12. typedef VOID (*PFN_GLYPHLOOP)(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  13. typedef VOID (*PFN_GLYPHLOOPN)(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
  14. PFN_GLYPHLOOP pfnGlyphLoop;
  15. //
  16. // debug routine
  17. //
  18. VOID
  19. exit_fast_text(
  20. LONG cyGlyph,
  21. LONG RightRot,
  22. LONG ulBufDelta,
  23. PUCHAR pGlyph,
  24. PUCHAR pBuffer,
  25. LONG cxGlyph
  26. )
  27. {
  28. return;
  29. }
  30. //
  31. // or_all_1_wide_rotated_need_last::
  32. // or_all_1_wide_rotated_no_last::
  33. // or_first_1_wide_rotated_need_last
  34. // or_first_1_wide_rotated_no_last::
  35. //
  36. VOID
  37. or_all_1_wide_rotated_need_last(
  38. LONG cyGlyph,
  39. LONG RightRot,
  40. LONG ulBufDelta,
  41. PUCHAR pGlyph,
  42. PUCHAR pBuffer,
  43. LONG cxGlyph
  44. )
  45. {
  46. PUCHAR pjEnd = pGlyph + cyGlyph;
  47. UCHAR c;
  48. do {
  49. c = *pGlyph++;
  50. *pBuffer |= c >> RightRot;
  51. pBuffer += ulBufDelta;
  52. } while (pGlyph != pjEnd);
  53. }
  54. //
  55. // mov_first_1_wide_rotated_need_last::
  56. // mov_first_1_wide_rotated_no_last::
  57. //
  58. VOID
  59. mov_first_1_wide_rotated_need_last(
  60. LONG cyGlyph,
  61. LONG RightRot,
  62. LONG ulBufDelta,
  63. PUCHAR pGlyph,
  64. PUCHAR pBuffer,
  65. LONG cxGlyph
  66. )
  67. {
  68. PUCHAR pjEnd = pGlyph + cyGlyph;
  69. UCHAR c;
  70. do {
  71. c = *pGlyph++;
  72. *pBuffer = c >> RightRot;
  73. pBuffer += ulBufDelta;
  74. } while (pGlyph != pjEnd);
  75. }
  76. //
  77. // mov_first_1_wide_unrotated::
  78. //
  79. VOID
  80. mov_first_1_wide_unrotated(
  81. LONG cyGlyph,
  82. LONG RightRot,
  83. LONG ulBufDelta,
  84. PUCHAR pGlyph,
  85. PUCHAR pBuffer,
  86. LONG cxGlyph
  87. )
  88. {
  89. PUCHAR pjEnd = pGlyph + cyGlyph;
  90. do {
  91. *pBuffer = *pGlyph++;
  92. pBuffer += ulBufDelta;
  93. } while (pGlyph != pjEnd);
  94. }
  95. //
  96. //or_all_1_wide_unrotated::
  97. //or_all_1_wide_unrotated_loop::
  98. //
  99. VOID
  100. or_all_1_wide_unrotated(
  101. LONG cyGlyph,
  102. LONG RightRot,
  103. LONG ulBufDelta,
  104. PUCHAR pGlyph,
  105. PUCHAR pBuffer,
  106. LONG cxGlyph
  107. )
  108. {
  109. PUCHAR pjEnd = pGlyph + cyGlyph;
  110. do {
  111. *pBuffer |= *pGlyph++;
  112. pBuffer += ulBufDelta;
  113. } while (pGlyph != pjEnd);
  114. }
  115. //
  116. // or_first_2_wide_rotated_need_last::
  117. //
  118. VOID
  119. or_first_2_wide_rotated_need_last(
  120. LONG cyGlyph,
  121. LONG RightRot,
  122. LONG ulBufDelta,
  123. PUCHAR pGlyph,
  124. PUCHAR pBuffer,
  125. LONG cxGlyph
  126. )
  127. {
  128. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  129. ULONG rl = 8-RightRot;
  130. UCHAR c0,c1;
  131. do {
  132. c0 = *pGlyph;
  133. c1 = *(pGlyph+1);
  134. pGlyph+=2;
  135. *pBuffer |= c0 >> RightRot;
  136. *(pBuffer+1) = (c1 >> RightRot) | (c0 << rl);
  137. pBuffer += ulBufDelta;
  138. } while (pGlyph != pjEnd);
  139. }
  140. //
  141. //or_all_2_wide_rotated_need_last::
  142. //
  143. VOID
  144. or_all_2_wide_rotated_need_last(
  145. LONG cyGlyph,
  146. LONG RightRot,
  147. LONG ulBufDelta,
  148. PUCHAR pGlyph,
  149. PUCHAR pBuffer,
  150. LONG cxGlyph
  151. )
  152. {
  153. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  154. ULONG rl = 8-RightRot;
  155. USHORT usTmp;
  156. UCHAR c0,c1;
  157. do {
  158. usTmp = *(PUSHORT)pGlyph;
  159. pGlyph += 2;
  160. c0 = (UCHAR)usTmp;
  161. c1 = (UCHAR)(usTmp >> 8);
  162. *pBuffer |= (UCHAR)(c0 >> RightRot);
  163. *(pBuffer+1) |= (UCHAR)((c1 >> RightRot) | (c0 << rl));
  164. pBuffer += ulBufDelta;
  165. } while (pGlyph != pjEnd);
  166. }
  167. //
  168. // mov_first_2_wide_rotated_need_last::
  169. //
  170. VOID
  171. mov_first_2_wide_rotated_need_last(
  172. LONG cyGlyph,
  173. LONG RightRot,
  174. LONG ulBufDelta,
  175. PUCHAR pGlyph,
  176. PUCHAR pBuffer,
  177. LONG cxGlyph
  178. )
  179. {
  180. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  181. ULONG rl = 8-RightRot;
  182. USHORT us;
  183. UCHAR c0;
  184. UCHAR c1;
  185. do {
  186. us = *(PUSHORT)pGlyph;
  187. c0 = (us & 0xff);
  188. c1 = us >> 8;
  189. pGlyph += 2;
  190. *pBuffer = c0 >> RightRot;
  191. *(pBuffer+1) = (c1 >> RightRot) | (c0 << rl);
  192. pBuffer += ulBufDelta;
  193. } while (pGlyph != pjEnd);
  194. }
  195. //
  196. // or_first_2_wide_rotated_no_last
  197. //
  198. VOID
  199. or_first_2_wide_rotated_no_last(
  200. LONG cyGlyph,
  201. LONG RightRot,
  202. LONG ulBufDelta,
  203. PUCHAR pGlyph,
  204. PUCHAR pBuffer,
  205. LONG cxGlyph
  206. )
  207. {
  208. PUCHAR pjEnd = pGlyph + cyGlyph;
  209. ULONG rl = 8-RightRot;
  210. UCHAR c0;
  211. do {
  212. c0 = *pGlyph++;
  213. *pBuffer |= c0 >> RightRot;
  214. *(pBuffer+1) = (c0 << rl);
  215. pBuffer += ulBufDelta;
  216. } while (pGlyph != pjEnd);
  217. }
  218. //
  219. //or_all_2_wide_rotated_no_last::
  220. //
  221. VOID
  222. or_all_2_wide_rotated_no_last(
  223. LONG cyGlyph,
  224. LONG RightRot,
  225. LONG ulBufDelta,
  226. PUCHAR pGlyph,
  227. PUCHAR pBuffer,
  228. LONG cxGlyph
  229. )
  230. {
  231. PUCHAR pjEnd = pGlyph + cyGlyph;
  232. ULONG rl = 8-RightRot;
  233. UCHAR c;
  234. do {
  235. c = *pGlyph;
  236. pGlyph ++;
  237. *pBuffer |= (UCHAR)(c >> RightRot);
  238. *(pBuffer+1) |= (UCHAR)(c << rl);
  239. pBuffer += ulBufDelta;
  240. } while (pGlyph != pjEnd);
  241. }
  242. //
  243. // or_all_2_wide_unrotated::
  244. //
  245. VOID
  246. or_all_2_wide_unrotated(
  247. LONG cyGlyph,
  248. LONG RightRot,
  249. LONG ulBufDelta,
  250. PUCHAR pGlyph,
  251. PUCHAR pBuffer,
  252. LONG cxGlyph
  253. )
  254. {
  255. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  256. //
  257. // aligned?
  258. //
  259. if ((ULONG_PTR)pBuffer & 0x01) {
  260. //
  261. // not aligned
  262. //
  263. USHORT usTmp;
  264. UCHAR c1,c0;
  265. do {
  266. usTmp = *(PUSHORT)pGlyph;
  267. pGlyph +=2;
  268. *pBuffer |= (UCHAR)usTmp;
  269. *(pBuffer+1) |= (UCHAR)(usTmp >> 8);
  270. pBuffer += ulBufDelta;
  271. } while (pGlyph != pjEnd);
  272. } else {
  273. //
  274. // aligned
  275. //
  276. USHORT usTmp;
  277. do {
  278. usTmp = *(PUSHORT)pGlyph;
  279. pGlyph +=2;
  280. *(PUSHORT)pBuffer |= usTmp;
  281. pBuffer += ulBufDelta;
  282. } while (pGlyph != pjEnd);
  283. }
  284. }
  285. //
  286. // mov_first_2_wide_unrotated::
  287. //
  288. VOID
  289. mov_first_2_wide_unrotated(
  290. LONG cyGlyph,
  291. LONG RightRot,
  292. LONG ulBufDelta,
  293. PUCHAR pGlyph,
  294. PUCHAR pBuffer,
  295. LONG cxGlyph
  296. )
  297. {
  298. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  299. USHORT us;
  300. do {
  301. us = *(PUSHORT)pGlyph;
  302. pGlyph +=2;
  303. *pBuffer = us & 0xff;
  304. *(pBuffer+1) = (UCHAR)(us >> 8);
  305. pBuffer += ulBufDelta;
  306. } while (pGlyph != pjEnd);
  307. }
  308. //
  309. // mov_first_2_wide_rotated_no_last::
  310. //
  311. VOID
  312. mov_first_2_wide_rotated_no_last(
  313. LONG cyGlyph,
  314. LONG RightRot,
  315. LONG ulBufDelta,
  316. PUCHAR pGlyph,
  317. PUCHAR pBuffer,
  318. LONG cxGlyph
  319. )
  320. {
  321. PUCHAR pjEnd = pGlyph + cyGlyph;
  322. ULONG rl = 8-RightRot;
  323. UCHAR c0;
  324. UCHAR c1;
  325. do {
  326. c0 = *pGlyph++;
  327. *pBuffer = c0 >> RightRot;
  328. *(pBuffer+1) = c0 << rl;
  329. pBuffer += ulBufDelta;
  330. } while (pGlyph != pjEnd);
  331. }
  332. //
  333. // or_first_3_wide_rotated_need_last::
  334. //
  335. VOID
  336. or_first_3_wide_rotated_need_last(
  337. LONG cyGlyph,
  338. LONG RightRot,
  339. LONG ulBufDelta,
  340. PUCHAR pGlyph,
  341. PUCHAR pBuffer,
  342. LONG cxGlyph
  343. )
  344. {
  345. PUCHAR pjEnd = pGlyph + 3*cyGlyph;
  346. ULONG ul;
  347. UCHAR c0,c1,c2;
  348. do {
  349. c0 = *pGlyph;
  350. c1 = *(pGlyph+1);
  351. c2 = *(pGlyph+2);
  352. //
  353. // make into big-endian ulong and shift
  354. //
  355. ul = (c0 << 16) | (c1 << 8) | c2;
  356. ul >>= RightRot;
  357. *pBuffer |= (BYTE)(ul >> 16);
  358. *(pBuffer+1) = (BYTE)(ul >> 8);
  359. *(pBuffer+2) = (BYTE)(ul);
  360. pGlyph += 3;
  361. pBuffer += ulBufDelta;
  362. } while (pGlyph != pjEnd);
  363. }
  364. //
  365. // or_all_3_wide_rotated_need_last::
  366. //
  367. VOID
  368. or_all_3_wide_rotated_need_last(
  369. LONG cyGlyph,
  370. LONG RightRot,
  371. LONG ulBufDelta,
  372. PUCHAR pGlyph,
  373. PUCHAR pBuffer,
  374. LONG cxGlyph
  375. )
  376. {
  377. PUCHAR pjEnd = pGlyph + 3*cyGlyph;
  378. ULONG ul;
  379. UCHAR c0,c1,c2;
  380. do {
  381. c0 = *pGlyph;
  382. c1 = *(pGlyph+1);
  383. c2 = *(pGlyph+2);
  384. //
  385. // make into big-endian ulong and shift
  386. //
  387. ul = (c0 << 16) | (c1 << 8) | c2;
  388. ul >>= RightRot;
  389. *pBuffer |= (BYTE)(ul >> 16);
  390. *(pBuffer+1) |= (BYTE)(ul >> 8);
  391. *(pBuffer+2) |= (BYTE)(ul);
  392. pGlyph += 3;
  393. pBuffer += ulBufDelta;
  394. } while (pGlyph != pjEnd);
  395. }
  396. //
  397. // or_all_3_wide_rotated_no_last::
  398. //
  399. VOID
  400. or_all_3_wide_rotated_no_last(
  401. LONG cyGlyph,
  402. LONG RightRot,
  403. LONG ulBufDelta,
  404. PUCHAR pGlyph,
  405. PUCHAR pBuffer,
  406. LONG cxGlyph
  407. )
  408. {
  409. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  410. ULONG ul;
  411. UCHAR c0,c1;
  412. do {
  413. c0 = *pGlyph;
  414. c1 = *(pGlyph+1);
  415. //
  416. // make big-endian and shift
  417. //
  418. ul = (c0 << 16) | (c1 << 8);
  419. ul >>= RightRot;
  420. //
  421. // store result
  422. //
  423. *pBuffer |= (BYTE)(ul >> 16);
  424. *(pBuffer+1) |= (BYTE)(ul >> 8);
  425. *(pBuffer+2) |= (BYTE)ul;
  426. pGlyph += 2;
  427. pBuffer += ulBufDelta;
  428. } while (pGlyph != pjEnd);
  429. }
  430. //
  431. // or_first_3_wide_rotated_no_last::
  432. //
  433. VOID
  434. or_first_3_wide_rotated_no_last(
  435. LONG cyGlyph,
  436. LONG RightRot,
  437. LONG ulBufDelta,
  438. PUCHAR pGlyph,
  439. PUCHAR pBuffer,
  440. LONG cxGlyph
  441. )
  442. {
  443. PUCHAR pjEnd = pGlyph + 2*cyGlyph;
  444. ULONG ul;
  445. UCHAR c0,c1;
  446. do {
  447. c0 = *pGlyph;
  448. c1 = *(pGlyph+1);
  449. //
  450. // make big-endian and shift
  451. //
  452. ul = (c0 << 16) | (c1 << 8);
  453. ul >>= RightRot;
  454. //
  455. // store result, only or in first byte
  456. //
  457. *pBuffer |= (BYTE)(ul >> 16);
  458. *(pBuffer+1) = (BYTE)(ul >> 8);
  459. *(pBuffer+2) = (BYTE)ul;
  460. pGlyph += 2;
  461. pBuffer += ulBufDelta;
  462. } while (pGlyph != pjEnd);
  463. }
  464. //
  465. // mov_first_3_wide_unrotated::
  466. //
  467. VOID
  468. mov_first_3_wide_unrotated(
  469. LONG cyGlyph,
  470. LONG RightRot,
  471. LONG ulBufDelta,
  472. PUCHAR pGlyph,
  473. PUCHAR pBuffer,
  474. LONG cxGlyph
  475. )
  476. {
  477. PUCHAR pjEnd = pGlyph + 3*cyGlyph;
  478. ULONG rl = 8-RightRot;
  479. UCHAR c0,c1,c2;
  480. do {
  481. c0 = *pGlyph;
  482. c1 = *(pGlyph+1);
  483. c2 = *(pGlyph+2);
  484. *pBuffer = c0;
  485. *(pBuffer+1) = c1;
  486. *(pBuffer+2) = c2;
  487. pGlyph += 3;
  488. pBuffer += ulBufDelta;
  489. } while (pGlyph != pjEnd);
  490. }
  491. //
  492. //or_all_3_wide_unrotated::
  493. //
  494. VOID
  495. or_all_3_wide_unrotated(
  496. LONG cyGlyph,
  497. LONG RightRot,
  498. LONG ulBufDelta,
  499. PUCHAR pGlyph,
  500. PUCHAR pBuffer,
  501. LONG cxGlyph
  502. )
  503. {
  504. PUCHAR pjEnd = pGlyph + 3*cyGlyph;
  505. ULONG rl = 8-RightRot;
  506. UCHAR c0,c1,c2;
  507. do {
  508. c0 = *pGlyph;
  509. c1 = *(pGlyph+1);
  510. c2 = *(pGlyph+2);
  511. *pBuffer |= c0;
  512. *(pBuffer+1) |= c1;
  513. *(pBuffer+2) |= c2;
  514. pBuffer += ulBufDelta;
  515. pGlyph += 3;
  516. } while (pGlyph != pjEnd);
  517. }
  518. //
  519. // or_first_4_wide_rotated_need_last::
  520. //
  521. VOID
  522. or_first_4_wide_rotated_need_last(
  523. LONG cyGlyph,
  524. LONG RightRot,
  525. LONG ulBufDelta,
  526. PUCHAR pGlyph,
  527. PUCHAR pBuffer,
  528. LONG cxGlyph
  529. )
  530. {
  531. PUCHAR pjEnd = pGlyph + 4*cyGlyph;
  532. ULONG ul;
  533. ULONG t0,t1,t2;
  534. do {
  535. ul = *(PULONG)pGlyph;
  536. //
  537. // endian swap
  538. //
  539. t0 = ul << 24;
  540. t1 = ul >> 24;
  541. t2 = (ul >> 8) & (0xff << 8);
  542. ul = (ul << 8) & (0xff << 16);
  543. ul = ul | t0 | t1 | t2;
  544. ul >>= RightRot;
  545. *pBuffer |= (BYTE)(ul >> 24);
  546. *(pBuffer+1) = (BYTE)(ul >> 16);
  547. *(pBuffer+2) = (BYTE)(ul >> 8);
  548. *(pBuffer+3) = (BYTE)(ul);
  549. pGlyph += 4;
  550. pBuffer += ulBufDelta;
  551. } while (pGlyph != pjEnd);
  552. }
  553. //
  554. // or_all_4_wide_rotated_need_last::
  555. //
  556. VOID
  557. or_all_4_wide_rotated_need_last(
  558. LONG cyGlyph,
  559. LONG RightRot,
  560. LONG ulBufDelta,
  561. PUCHAR pGlyph,
  562. PUCHAR pBuffer,
  563. LONG cxGlyph
  564. )
  565. {
  566. PUCHAR pjEnd = pGlyph + 4*cyGlyph;
  567. ULONG ul;
  568. ULONG t0,t1,t2;
  569. do {
  570. ul = *(PULONG)pGlyph;
  571. //
  572. // endian swap
  573. //
  574. t0 = ul << 24;
  575. t1 = ul >> 24;
  576. t2 = (ul >> 8) & (0xff << 8);
  577. ul = (ul << 8) & (0xff << 16);
  578. ul = ul | t0 | t1 | t2;
  579. ul >>= RightRot;
  580. *pBuffer |= (BYTE)(ul >> 24);
  581. *(pBuffer+1) |= (BYTE)(ul >> 16);
  582. *(pBuffer+2) |= (BYTE)(ul >> 8);
  583. *(pBuffer+3) |= (BYTE)(ul);
  584. pGlyph += 4;
  585. pBuffer += ulBufDelta;
  586. } while (pGlyph != pjEnd);
  587. }
  588. //
  589. // or_first_4_wide_rotated_no_last::
  590. //
  591. VOID
  592. or_first_4_wide_rotated_no_last(
  593. LONG cyGlyph,
  594. LONG RightRot,
  595. LONG ulBufDelta,
  596. PUCHAR pGlyph,
  597. PUCHAR pBuffer,
  598. LONG cxGlyph
  599. )
  600. {
  601. PBYTE pjEnd = pGlyph + 3*cyGlyph;
  602. BYTE c0,c1,c2;
  603. ULONG ul;
  604. while (pGlyph != pjEnd) {
  605. //
  606. // load src
  607. //
  608. c0 = *pGlyph;
  609. c1 = *(pGlyph+1);
  610. c2 = *(pGlyph+2);
  611. //
  612. // or into big endian ULONG and shift
  613. //
  614. ul = (c0 << 24) | (c1 << 16) | (c2 << 8);
  615. ul >>= RightRot;
  616. //
  617. // store result, ony or in fisrt byte
  618. //
  619. *pBuffer |= (BYTE)(ul >> 24);
  620. *(pBuffer+1) = (BYTE)(ul >> 16);;
  621. *(pBuffer+2) = (BYTE)(ul >> 8);
  622. *(pBuffer+3) = (BYTE)(ul);
  623. //
  624. // inc scan line
  625. //
  626. pGlyph += 3;
  627. pBuffer += ulBufDelta;
  628. }
  629. }
  630. //
  631. // or_all_4_wide_rotated_no_last::
  632. //
  633. VOID
  634. or_all_4_wide_rotated_no_last(
  635. LONG cyGlyph,
  636. LONG RightRot,
  637. LONG ulBufDelta,
  638. PUCHAR pGlyph,
  639. PUCHAR pBuffer,
  640. LONG cxGlyph
  641. )
  642. {
  643. PBYTE pjEnd = pGlyph + 3*cyGlyph;
  644. BYTE c0,c1,c2;
  645. ULONG ul;
  646. while (pGlyph != pjEnd) {
  647. //
  648. // load src
  649. //
  650. c0 = *pGlyph;
  651. c1 = *(pGlyph+1);
  652. c2 = *(pGlyph+2);
  653. //
  654. // or into big endian ULONG and shift
  655. //
  656. ul = (c0 << 24) | (c1 << 16) | (c2 << 8);
  657. ul >>= RightRot;
  658. //
  659. // store result
  660. //
  661. *pBuffer |= (BYTE)(ul >> 24);
  662. *(pBuffer+1) |= (BYTE)(ul >> 16);;
  663. *(pBuffer+2) |= (BYTE)(ul >> 8);
  664. *(pBuffer+3) |= (BYTE)(ul);
  665. //
  666. // inc scan line
  667. //
  668. pGlyph += 3;
  669. pBuffer += ulBufDelta;
  670. }
  671. }
  672. VOID
  673. mov_first_4_wide_unrotated(
  674. LONG cyGlyph,
  675. LONG RightRot,
  676. LONG ulBufDelta,
  677. PUCHAR pGlyph,
  678. PUCHAR pBuffer,
  679. LONG cxGlyph
  680. )
  681. {
  682. PUCHAR pjEnd = pGlyph + 4*cyGlyph;
  683. switch ((ULONG_PTR)pBuffer & 0x03 ) {
  684. case 0:
  685. while (pGlyph != pjEnd) {
  686. *(PULONG)pBuffer = *(PULONG)pGlyph;
  687. pGlyph += 4;
  688. pBuffer += ulBufDelta;
  689. }
  690. break;
  691. case 1:
  692. case 3:
  693. while (pGlyph != pjEnd) {
  694. *pBuffer = *pGlyph;
  695. *(pBuffer+1) = *(pGlyph+1);
  696. *(pBuffer+2) = *(pGlyph+2);
  697. *(pBuffer+3) = *(pGlyph+3);
  698. pGlyph += 4;
  699. pBuffer += ulBufDelta;
  700. }
  701. break;
  702. case 2:
  703. while (pGlyph != pjEnd) {
  704. *(PUSHORT)(pBuffer) = *(PUSHORT)pGlyph;
  705. *(PUSHORT)(pBuffer+2) = *(PUSHORT)(pGlyph+2);
  706. pBuffer += ulBufDelta;
  707. pGlyph += 4;
  708. }
  709. break;
  710. }
  711. }
  712. //
  713. // or_all_4_wide_unrotated::
  714. //
  715. VOID
  716. or_all_4_wide_unrotated(
  717. LONG cyGlyph,
  718. LONG RightRot,
  719. LONG ulBufDelta,
  720. PUCHAR pGlyph,
  721. PUCHAR pBuffer,
  722. LONG cxGlyph
  723. )
  724. {
  725. PUCHAR pjEnd = pGlyph + 4*cyGlyph;
  726. switch ((ULONG_PTR)pBuffer & 0x03 ) {
  727. case 0:
  728. while (pGlyph != pjEnd) {
  729. *(PULONG)pBuffer |= *(PULONG)pGlyph;
  730. pGlyph += 4;
  731. pBuffer += ulBufDelta;
  732. }
  733. break;
  734. case 1:
  735. case 3:
  736. while (pGlyph != pjEnd) {
  737. *pBuffer |= *pGlyph;
  738. *(pBuffer+1) |= *(pGlyph+1);
  739. *(pBuffer+2) |= *(pGlyph+2);
  740. *(pBuffer+3) |= *(pGlyph+3);
  741. pGlyph += 4;
  742. pBuffer += ulBufDelta;
  743. }
  744. break;
  745. case 2:
  746. while (pGlyph != pjEnd) {
  747. *(PUSHORT)pBuffer |= *(PUSHORT)pGlyph;
  748. *(PUSHORT)(pBuffer+2) |= *(PUSHORT)(pGlyph+2);
  749. pGlyph += 4;
  750. pBuffer += ulBufDelta;
  751. }
  752. break;
  753. }
  754. }
  755. /******************************Public*Routine******************************\
  756. *
  757. * Routine Name
  758. *
  759. * or_first_N_wide_rotated_need_last
  760. *
  761. *
  762. * Routine Description:
  763. *
  764. * Draw arbitrarily wide glyphs to 1BPP temp buffer
  765. *
  766. *
  767. * Arguments:
  768. *
  769. * cyGlyph - glyph height
  770. * RightRot - alignment
  771. * ulBufDelta - scan line stride of temp buffer
  772. * pGlyph - pointer to glyph bitmap
  773. * pBuffer - pointer to temp buffer
  774. * cxGlyph - glyph width in pixels
  775. * cxDst - Dest width in bytes
  776. *
  777. * Return Value:
  778. *
  779. * None
  780. *
  781. \**************************************************************************/
  782. VOID
  783. or_first_N_wide_rotated_need_last(
  784. LONG cyGlyph,
  785. LONG RightRot,
  786. LONG ulBufDelta,
  787. PUCHAR pGlyph,
  788. PUCHAR pBuffer,
  789. LONG cxGlyph,
  790. LONG cxDst
  791. )
  792. {
  793. PUCHAR pjDst = (PUCHAR)pBuffer;
  794. PUCHAR pjDstEnd;
  795. PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  796. LONG lStride = ulBufDelta - cxDst;
  797. LONG rl = 8-RightRot;
  798. //
  799. // source doesn't advance after first byte, and
  800. // we do the first byte outside the loop
  801. //
  802. do {
  803. UCHAR c0 = *pGlyph++;
  804. UCHAR c1;
  805. pjDstEnd = pjDst + cxDst;
  806. *pjDst |= c0 >> RightRot;
  807. pjDst++;
  808. c1 = c0 << rl;
  809. //
  810. // know cxDst is at least 4, use do-while
  811. //
  812. do {
  813. c0 = *pGlyph;
  814. *pjDst = (c0 >> RightRot) | c1;
  815. c1 = c0 << rl;
  816. pjDst++;
  817. pGlyph++;
  818. } while (pjDst != pjDstEnd);
  819. pjDst += lStride;
  820. } while (pjDst != pjDstEndy);
  821. }
  822. VOID
  823. or_all_N_wide_rotated_need_last(
  824. LONG cyGlyph,
  825. LONG RightRot,
  826. LONG ulBufDelta,
  827. PUCHAR pGlyph,
  828. PUCHAR pBuffer,
  829. LONG cxGlyph,
  830. LONG cxDst
  831. )
  832. {
  833. PUCHAR pjDst = (PUCHAR)pBuffer;
  834. PUCHAR pjDstEnd;
  835. PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  836. LONG lStride = ulBufDelta - cxDst;
  837. LONG rl = 8-RightRot;
  838. //
  839. // source doesn't advance after first byte, and
  840. // we do the first byte outside the loop
  841. //
  842. do {
  843. UCHAR c0 = *pGlyph++;
  844. UCHAR c1;
  845. pjDstEnd = pjDst + cxDst;
  846. *pjDst |= c0 >> RightRot;
  847. pjDst++;
  848. c1 = c0 << rl;
  849. //
  850. // know cxDst is at least 4, use do-while
  851. //
  852. do {
  853. c0 = *pGlyph;
  854. *pjDst |= ((c0 >> RightRot) | c1);
  855. c1 = c0 << rl;
  856. pjDst++;
  857. pGlyph++;
  858. } while (pjDst != pjDstEnd);
  859. pjDst += lStride;
  860. } while (pjDst != pjDstEndy);
  861. }
  862. VOID
  863. or_first_N_wide_rotated_no_last(
  864. LONG cyGlyph,
  865. LONG RightRot,
  866. LONG ulBufDelta,
  867. PUCHAR pGlyph,
  868. PUCHAR pBuffer,
  869. LONG cxGlyph,
  870. LONG cxDst
  871. )
  872. {
  873. PUCHAR pjDst = (PUCHAR)pBuffer;
  874. PUCHAR pjDstEnd;
  875. PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  876. LONG lStride = ulBufDelta - cxDst;
  877. LONG rl = 8-RightRot;
  878. //
  879. // source doesn't advance after first byte, and
  880. // we do the first byte outside the loop
  881. //
  882. do {
  883. UCHAR c0;
  884. UCHAR c1;
  885. pjDstEnd = pjDst + cxDst - 1;
  886. //
  887. // do first dest byte outside loop for OR
  888. //
  889. c1 = 0;
  890. c0 = *pGlyph;
  891. *pjDst |= ((c0 >> RightRot) | c1);
  892. pjDst++;
  893. pGlyph++;
  894. //
  895. // know cxDst is at least 4, use do-while
  896. //
  897. do {
  898. c0 = *pGlyph;
  899. *pjDst = ((c0 >> RightRot) | c1);
  900. c1 = c0 << rl;
  901. pjDst++;
  902. pGlyph++;
  903. } while (pjDst != pjDstEnd);
  904. //
  905. // last dst byte outside loop, no new src needed
  906. //
  907. *pjDst = c1;
  908. pjDst++;
  909. pjDst += lStride;
  910. } while (pjDst != pjDstEndy);
  911. }
  912. VOID
  913. or_all_N_wide_rotated_no_last(
  914. LONG cyGlyph,
  915. LONG RightRot,
  916. LONG ulBufDelta,
  917. PUCHAR pGlyph,
  918. PUCHAR pBuffer,
  919. LONG cxGlyph,
  920. LONG cxDst
  921. )
  922. {
  923. PUCHAR pjDst = (PUCHAR)pBuffer;
  924. PUCHAR pjDstEnd;
  925. PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  926. LONG lStride = ulBufDelta - cxDst;
  927. LONG rl = 8-RightRot;
  928. //
  929. // source doesn't advance after first byte, and
  930. // we do the first byte outside the loop
  931. //
  932. do {
  933. UCHAR c0;
  934. UCHAR c1;
  935. pjDstEnd = pjDst + cxDst - 1;
  936. //
  937. // do first dest byte outside loop for OR
  938. //
  939. c1 = 0;
  940. //
  941. // know cxDst is at least 4, use do-while
  942. //
  943. do {
  944. c0 = *pGlyph;
  945. *pjDst |= ((c0 >> RightRot) | c1);
  946. c1 = c0 << rl;
  947. pjDst++;
  948. pGlyph++;
  949. } while (pjDst != pjDstEnd);
  950. //
  951. // last dst byte outside loop, no new src needed
  952. //
  953. *pjDst |= c1;
  954. pjDst++;
  955. pjDst += lStride;
  956. } while (pjDst != pjDstEndy);
  957. }
  958. //
  959. // The following routines can be significantly sped up by
  960. // breaking them out into DWORD alignment cases.
  961. //
  962. VOID
  963. mov_first_N_wide_unrotated(
  964. LONG cyGlyph,
  965. LONG RightRot,
  966. LONG ulBufDelta,
  967. PUCHAR pGlyph,
  968. PUCHAR pBuffer,
  969. LONG cxGlyph,
  970. LONG cxDst
  971. )
  972. {
  973. PUCHAR pjDst = (PUCHAR)pBuffer;
  974. PUCHAR pjDstEnd;
  975. PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  976. LONG lStride = ulBufDelta - cxDst;
  977. //
  978. // byte aligned copy
  979. //
  980. do {
  981. pjDstEnd = pjDst + cxDst;
  982. //
  983. // let compiler unroll inner loop
  984. //
  985. do {
  986. *pjDst++ = *pGlyph++;
  987. } while (pjDst != pjDstEnd );
  988. pjDst += lStride;
  989. } while (pjDst != pjDstEndy);
  990. }
  991. VOID
  992. or_all_N_wide_unrotated(
  993. LONG cyGlyph,
  994. LONG RightRot,
  995. LONG ulBufDelta,
  996. PUCHAR pGlyph,
  997. PUCHAR pBuffer,
  998. LONG cxGlyph,
  999. LONG cxDst
  1000. )
  1001. {
  1002. PUCHAR pjDst = (PUCHAR)pBuffer;
  1003. PUCHAR pjDstEnd;
  1004. PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
  1005. LONG lStride = ulBufDelta - cxDst;
  1006. //
  1007. // byte aligned copy
  1008. //
  1009. do {
  1010. pjDstEnd = pjDst + cxDst;
  1011. //
  1012. // let compiler unroll inner loop
  1013. //
  1014. do {
  1015. *pjDst++ |= *pGlyph++;
  1016. } while (pjDst != pjDstEnd );
  1017. pjDst += lStride;
  1018. } while (pjDst != pjDstEndy);
  1019. }
  1020. VOID exit_fast_text(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1021. VOID or_all_1_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1022. VOID or_all_1_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1023. VOID or_all_1_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1024. VOID or_all_2_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1025. VOID or_all_2_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1026. VOID or_all_2_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1027. VOID or_all_2_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1028. VOID or_all_3_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1029. VOID or_all_3_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1030. VOID or_all_3_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1031. VOID or_all_3_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1032. VOID or_all_4_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1033. VOID or_all_4_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1034. VOID or_all_4_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1035. VOID or_all_4_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
  1036. VOID or_all_N_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
  1037. VOID or_all_N_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
  1038. VOID or_all_N_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
  1039. VOID or_all_N_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
  1040. PVOID OrAllTableNarrow[] = {
  1041. exit_fast_text,
  1042. exit_fast_text,
  1043. exit_fast_text,
  1044. exit_fast_text,
  1045. or_all_1_wide_rotated_need_last,
  1046. or_all_1_wide_unrotated,
  1047. or_all_1_wide_rotated_need_last,
  1048. or_all_1_wide_unrotated,
  1049. or_all_2_wide_rotated_need_last,
  1050. or_all_2_wide_unrotated,
  1051. or_all_2_wide_rotated_no_last,
  1052. or_all_2_wide_unrotated,
  1053. or_all_3_wide_rotated_need_last,
  1054. or_all_3_wide_unrotated,
  1055. or_all_3_wide_rotated_no_last,
  1056. or_all_3_wide_unrotated,
  1057. or_all_4_wide_rotated_need_last,
  1058. or_all_4_wide_unrotated,
  1059. or_all_4_wide_rotated_no_last,
  1060. or_all_4_wide_unrotated
  1061. };
  1062. PVOID OrInitialTableNarrow[] = {
  1063. exit_fast_text ,
  1064. exit_fast_text ,
  1065. exit_fast_text ,
  1066. exit_fast_text ,
  1067. or_all_1_wide_rotated_need_last ,
  1068. mov_first_1_wide_unrotated ,
  1069. or_all_1_wide_rotated_need_last ,
  1070. mov_first_1_wide_unrotated ,
  1071. or_first_2_wide_rotated_need_last ,
  1072. mov_first_2_wide_unrotated ,
  1073. or_first_2_wide_rotated_no_last ,
  1074. mov_first_2_wide_unrotated ,
  1075. or_first_3_wide_rotated_need_last ,
  1076. mov_first_3_wide_unrotated ,
  1077. or_first_3_wide_rotated_no_last ,
  1078. mov_first_3_wide_unrotated ,
  1079. or_first_4_wide_rotated_need_last ,
  1080. mov_first_4_wide_unrotated ,
  1081. or_first_4_wide_rotated_no_last ,
  1082. mov_first_4_wide_unrotated
  1083. };
  1084. //
  1085. // Handles arbitrarily wide glyph drawing, for case where initial byte should be
  1086. // ORed if it's not aligned (intended for use in drawing all but the first glyph
  1087. // in a string). Table format is:
  1088. // Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  1089. // Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  1090. //
  1091. PVOID OrInitialTableWide[] = {
  1092. or_first_N_wide_rotated_need_last,
  1093. mov_first_N_wide_unrotated,
  1094. or_first_N_wide_rotated_no_last,
  1095. mov_first_N_wide_unrotated
  1096. };
  1097. //
  1098. // Handles arbitrarily wide glyph drawing, for case where all bytes should
  1099. // be ORed (intended for use in drawing potentially overlapping glyphs).
  1100. // Table format is:
  1101. // Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  1102. // Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  1103. //
  1104. //
  1105. PVOID OrAllTableWide[] = {
  1106. or_all_N_wide_rotated_need_last,
  1107. or_all_N_wide_unrotated,
  1108. or_all_N_wide_rotated_no_last,
  1109. or_all_N_wide_unrotated
  1110. };
  1111. /******************************Public*Routine******************************\
  1112. *
  1113. * Routine Name
  1114. *
  1115. * draw_nf_ntb_o_to_temp_start
  1116. *
  1117. * Routine Description:
  1118. *
  1119. * Specialized glyph dispatch routine for non-fixed pitch, top and
  1120. * bottom not aligned glyphs that do overlap. This routine calculates
  1121. * the glyph's position on the temp buffer, then determines the correct
  1122. * highly specialized routine to be used to draw each glyph based on
  1123. * the glyph width, alignment and rotation
  1124. *
  1125. * Arguments:
  1126. *
  1127. * pGlyphPos - Pointer to first in list of GLYPHPOS structs
  1128. * cGlyph - Number of glyphs to draw
  1129. * pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
  1130. * ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
  1131. * TempBufDelta - Scan line Delta for TempBuffer (always pos)
  1132. *
  1133. * Return Value:
  1134. *
  1135. * None
  1136. *
  1137. \**************************************************************************/
  1138. VOID
  1139. draw_nf_ntb_o_to_temp_start(
  1140. PGLYPHPOS pGlyphPos,
  1141. ULONG cGlyphs,
  1142. PUCHAR pjTempBuffer,
  1143. ULONG ulLeftEdge,
  1144. ULONG TempBufDelta,
  1145. ULONG ulCharInc,
  1146. ULONG ulTempTop
  1147. )
  1148. {
  1149. LONG NumScans;
  1150. LONG RightRot;
  1151. PBYTE pGlyphData;
  1152. PBYTE pTempOutput;
  1153. GLYPHBITS *pGlyphBits;
  1154. LONG GlyphPosX;
  1155. LONG GlyphPixels;
  1156. LONG GlyphAlignment;
  1157. LONG SrcBytes;
  1158. LONG DstBytes;
  1159. ULONG ulDrawFlag;
  1160. PFN_GLYPHLOOPN pfnGlyphLoopN;
  1161. PFN_GLYPHLOOP pfnGlyphLoop;
  1162. ULONG iGlyph = 0;
  1163. LONG GlyphPosY;
  1164. //
  1165. // Draw non fixed pitch, tops and bottoms not aligned,overlap
  1166. //
  1167. while (cGlyphs--) {
  1168. pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
  1169. //
  1170. // Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xffffffe0)
  1171. //
  1172. GlyphPosX = pGlyphPos[iGlyph].ptl.x + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x - ulLeftEdge;
  1173. GlyphPosY = pGlyphPos[iGlyph].ptl.y + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.y - ulTempTop ;
  1174. GlyphAlignment = GlyphPosX & 0x07;
  1175. //
  1176. // calc byte offset
  1177. //
  1178. pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
  1179. //
  1180. // glyph width
  1181. //
  1182. GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
  1183. //
  1184. // source and dest bytes required
  1185. //
  1186. DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
  1187. SrcBytes = (GlyphPixels + 7) >> 3;
  1188. pTempOutput += (GlyphPosY * TempBufDelta);
  1189. if (DstBytes <= 4) {
  1190. //
  1191. // use narrow initial table
  1192. //
  1193. ulDrawFlag = (
  1194. (DstBytes << 2) |
  1195. ((DstBytes > SrcBytes) << 1) |
  1196. ((GlyphAlignment == 0))
  1197. );
  1198. pfnGlyphLoop = (PFN_GLYPHLOOP)OrAllTableNarrow[ulDrawFlag];
  1199. pfnGlyphLoop(
  1200. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1201. GlyphAlignment,
  1202. TempBufDelta,
  1203. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1204. pTempOutput,
  1205. SrcBytes
  1206. );
  1207. } else {
  1208. //
  1209. // use wide glyph drawing
  1210. //
  1211. ulDrawFlag = (
  1212. ((DstBytes > SrcBytes) << 1) |
  1213. ((GlyphAlignment == 0))
  1214. );
  1215. pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
  1216. pfnGlyphLoopN(
  1217. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1218. GlyphAlignment,
  1219. TempBufDelta,
  1220. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1221. pTempOutput,
  1222. SrcBytes,
  1223. DstBytes
  1224. );
  1225. }
  1226. iGlyph++;
  1227. }
  1228. }
  1229. /******************************Public*Routine******************************\
  1230. *
  1231. * Routine Name
  1232. *
  1233. * draw_f_ntb_o_to_temp_start
  1234. *
  1235. * Routine Description:
  1236. *
  1237. * Specialized glyph dispatch routine for fixed pitch, top and
  1238. * bottom not aligned glyphs that do overlap. This routine calculates
  1239. * the glyph's position on the temp buffer, then determines the correct
  1240. * highly specialized routine to be used to draw each glyph based on
  1241. * the glyph width, alignment and rotation
  1242. *
  1243. * Arguments:
  1244. *
  1245. * pGlyphPos - Pointer to first in list of GLYPHPOS structs
  1246. * cGlyph - Number of glyphs to draw
  1247. * pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
  1248. * ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
  1249. * TempBufDelta - Scan line Delta for TempBuffer (always pos)
  1250. *
  1251. * Return Value:
  1252. *
  1253. * None
  1254. *
  1255. \**************************************************************************/
  1256. VOID
  1257. draw_f_ntb_o_to_temp_start(
  1258. PGLYPHPOS pGlyphPos,
  1259. ULONG cGlyphs,
  1260. PUCHAR pjTempBuffer,
  1261. ULONG ulLeftEdge,
  1262. ULONG TempBufDelta,
  1263. ULONG ulCharInc,
  1264. ULONG ulTempTop
  1265. )
  1266. {
  1267. LONG NumScans;
  1268. LONG RightRot;
  1269. PBYTE pGlyphData;
  1270. PBYTE pTempOutput;
  1271. GLYPHBITS *pGlyphBits;
  1272. LONG GlyphPosX;
  1273. LONG GlyphPixels;
  1274. LONG GlyphAlignment;
  1275. LONG SrcBytes;
  1276. LONG DstBytes;
  1277. ULONG ulDrawFlag;
  1278. PFN_GLYPHLOOP pfnGlyphLoop;
  1279. PFN_GLYPHLOOPN pfnGlyphLoopN;
  1280. ULONG iGlyph = 0;
  1281. LONG GlyphPitchX;
  1282. LONG GlyphPitchY;
  1283. LONG GlyphPosY;
  1284. //
  1285. // Draw fixed pitch, tops and bottoms not aligned,overlap
  1286. //
  1287. GlyphPitchX = pGlyphPos->ptl.x - ulLeftEdge;
  1288. GlyphPitchY = pGlyphPos->ptl.y - ulTempTop;
  1289. while (cGlyphs--) {
  1290. pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
  1291. //
  1292. // Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xfffffff8)
  1293. //
  1294. GlyphPosX = GlyphPitchX + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x;
  1295. GlyphPosY = GlyphPitchY + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.y;
  1296. GlyphAlignment = GlyphPosX & 0x07;
  1297. //
  1298. // calc byte offset
  1299. //
  1300. pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
  1301. //
  1302. // glyph width
  1303. //
  1304. GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
  1305. //
  1306. // source and dest bytes required
  1307. //
  1308. DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
  1309. SrcBytes = (GlyphPixels + 7) >> 3;
  1310. //
  1311. // calc glyph destination scan line
  1312. //
  1313. pTempOutput += (GlyphPosY * TempBufDelta);
  1314. if (DstBytes <= 4) {
  1315. //
  1316. // use narrow initial table
  1317. //
  1318. ulDrawFlag = (
  1319. (DstBytes << 2) |
  1320. ((DstBytes > SrcBytes) << 1) |
  1321. ((GlyphAlignment == 0))
  1322. );
  1323. pfnGlyphLoop = (PFN_GLYPHLOOP)OrAllTableNarrow[ulDrawFlag];
  1324. pfnGlyphLoop(
  1325. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1326. GlyphAlignment,
  1327. TempBufDelta,
  1328. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1329. pTempOutput,
  1330. SrcBytes
  1331. );
  1332. } else {
  1333. //
  1334. // use wide glyph drawing
  1335. //
  1336. ulDrawFlag = (
  1337. ((DstBytes > SrcBytes) << 1) |
  1338. ((GlyphAlignment == 0))
  1339. );
  1340. pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
  1341. pfnGlyphLoopN(
  1342. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1343. GlyphAlignment,
  1344. TempBufDelta,
  1345. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1346. pTempOutput,
  1347. SrcBytes,
  1348. DstBytes
  1349. );
  1350. }
  1351. GlyphPitchX += ulCharInc;
  1352. iGlyph++;
  1353. }
  1354. }
  1355. /******************************Public*Routine******************************\
  1356. *
  1357. * Routine Name
  1358. *
  1359. * draw_nf_tb_no_to_temp_start
  1360. *
  1361. * Routine Description:
  1362. *
  1363. * Specialized glyph dispatch routine for non-fixed pitch, top and
  1364. * bottom aligned glyphs that do not overlap. This routine calculates
  1365. * the glyph's position on the temp buffer, then determines the correct
  1366. * highly specialized routine to be used to draw each glyph based on
  1367. * the glyph width, alignment and rotation
  1368. *
  1369. * Arguments:
  1370. *
  1371. * pGlyphPos - Pointer to first in list of GLYPHPOS structs
  1372. * cGlyph - Number of glyphs to draw
  1373. * pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
  1374. * ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
  1375. * TempBufDelta - Scan line Delta for TempBuffer (always pos)
  1376. *
  1377. * Return Value:
  1378. *
  1379. * None
  1380. *
  1381. \**************************************************************************/
  1382. VOID
  1383. draw_nf_tb_no_to_temp_start(
  1384. PGLYPHPOS pGlyphPos,
  1385. ULONG cGlyphs,
  1386. PUCHAR pjTempBuffer,
  1387. ULONG ulLeftEdge,
  1388. ULONG TempBufDelta,
  1389. ULONG ulCharInc,
  1390. ULONG ulTempTop
  1391. )
  1392. {
  1393. LONG NumScans;
  1394. LONG RightRot;
  1395. PBYTE pGlyphData;
  1396. PBYTE pTempOutput;
  1397. GLYPHBITS *pGlyphBits;
  1398. LONG GlyphPosX;
  1399. LONG GlyphPixels;
  1400. LONG GlyphAlignment;
  1401. LONG SrcBytes;
  1402. LONG DstBytes;
  1403. ULONG ulDrawFlag;
  1404. PFN_GLYPHLOOP pfnGlyphLoop;
  1405. PFN_GLYPHLOOPN pfnGlyphLoopN;
  1406. ULONG iGlyph = 0;
  1407. //
  1408. // Draw non fixed pitch, tops and bottoms not aligned,overlap
  1409. //
  1410. while (cGlyphs--) {
  1411. pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
  1412. //
  1413. // Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xfffffff8)
  1414. //
  1415. GlyphPosX = pGlyphPos[iGlyph].ptl.x + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x - ulLeftEdge;
  1416. GlyphAlignment = GlyphPosX & 0x07;
  1417. //
  1418. // calc byte offset
  1419. //
  1420. pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
  1421. //
  1422. // glyph width
  1423. //
  1424. GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
  1425. //
  1426. // source and dest bytes required
  1427. //
  1428. DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
  1429. SrcBytes = (GlyphPixels + 7) >> 3;
  1430. if (DstBytes <= 4) {
  1431. //
  1432. // use narrow initial table
  1433. //
  1434. ulDrawFlag = (
  1435. (DstBytes << 2) |
  1436. ((DstBytes > SrcBytes) << 1) |
  1437. ((GlyphAlignment == 0))
  1438. );
  1439. pfnGlyphLoop = (PFN_GLYPHLOOP)OrInitialTableNarrow[ulDrawFlag];
  1440. pfnGlyphLoop(
  1441. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1442. GlyphAlignment,
  1443. TempBufDelta,
  1444. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1445. pTempOutput,
  1446. SrcBytes
  1447. );
  1448. } else {
  1449. //
  1450. // use wide glyph drawing
  1451. //
  1452. ulDrawFlag = (
  1453. ((DstBytes > SrcBytes) << 1) |
  1454. ((GlyphAlignment == 0))
  1455. );
  1456. pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
  1457. pfnGlyphLoopN(
  1458. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1459. GlyphAlignment,
  1460. TempBufDelta,
  1461. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1462. pTempOutput,
  1463. SrcBytes,
  1464. DstBytes
  1465. );
  1466. }
  1467. iGlyph++;
  1468. }
  1469. }
  1470. /******************************Public*Routine******************************\
  1471. *
  1472. * Routine Name
  1473. *
  1474. * draw_f_tb_no_to_temp_start
  1475. *
  1476. * Routine Description:
  1477. *
  1478. * Specialized glyph dispatch routine for fixed pitch, top and
  1479. * bottom aligned glyphs that do not overlap. This routine calculates
  1480. * the glyph's position on the temp buffer, then determines the correct
  1481. * highly specialized routine to be used to draw each glyph based on
  1482. * the glyph width, alignment and rotation
  1483. *
  1484. * Arguments:
  1485. *
  1486. * pGlyphPos - Pointer to first in list of GLYPHPOS structs
  1487. * cGlyph - Number of glyphs to draw
  1488. * pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
  1489. * ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
  1490. * TempBufDelta - Scan line Delta for TempBuffer (always pos)
  1491. *
  1492. * Return Value:
  1493. *
  1494. * None
  1495. *
  1496. \**************************************************************************/
  1497. VOID
  1498. draw_f_tb_no_to_temp_start(
  1499. PGLYPHPOS pGlyphPos,
  1500. ULONG cGlyphs,
  1501. PUCHAR pjTempBuffer,
  1502. ULONG ulLeftEdge,
  1503. ULONG TempBufDelta,
  1504. ULONG ulCharInc,
  1505. ULONG ulTempTop
  1506. )
  1507. {
  1508. LONG NumScans;
  1509. LONG RightRot;
  1510. PBYTE pGlyphData;
  1511. PBYTE pTempOutput;
  1512. GLYPHBITS *pGlyphBits;
  1513. LONG GlyphPosX;
  1514. LONG GlyphPixels;
  1515. LONG GlyphAlignment;
  1516. LONG SrcBytes;
  1517. LONG DstBytes;
  1518. ULONG ulDrawFlag;
  1519. PFN_GLYPHLOOPN pfnGlyphLoopN;
  1520. PFN_GLYPHLOOP pfnGlyphLoop;
  1521. ULONG iGlyph = 0;
  1522. LONG GlyphPitchX;
  1523. GlyphPitchX = pGlyphPos->ptl.x;
  1524. //
  1525. // Draw fixed pitch, tops and bottoms not aligned,overlap
  1526. //
  1527. while (cGlyphs--) {
  1528. pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
  1529. //
  1530. // Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xfffffff8)
  1531. //
  1532. GlyphPosX = GlyphPitchX + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x - ulLeftEdge;
  1533. GlyphAlignment = GlyphPosX & 0x07;
  1534. //
  1535. // calc byte offset
  1536. //
  1537. pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
  1538. //
  1539. // glyph width
  1540. //
  1541. GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
  1542. //
  1543. // source and dest bytes required
  1544. //
  1545. DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
  1546. SrcBytes = (GlyphPixels + 7) >> 3;
  1547. if (DstBytes <= 4) {
  1548. //
  1549. // use narrow initial table
  1550. //
  1551. ulDrawFlag = (
  1552. (DstBytes << 2) |
  1553. ((DstBytes > SrcBytes) << 1) |
  1554. (GlyphAlignment == 0)
  1555. );
  1556. pfnGlyphLoop = (PFN_GLYPHLOOP)OrInitialTableNarrow[ulDrawFlag];
  1557. pfnGlyphLoop(
  1558. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1559. GlyphAlignment,
  1560. TempBufDelta,
  1561. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1562. pTempOutput,
  1563. SrcBytes
  1564. );
  1565. } else {
  1566. //
  1567. // use wide glyph drawing
  1568. //
  1569. ulDrawFlag = (
  1570. ((DstBytes > SrcBytes) << 1) |
  1571. ((GlyphAlignment == 0))
  1572. );
  1573. pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
  1574. pfnGlyphLoopN(
  1575. pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
  1576. GlyphAlignment,
  1577. TempBufDelta,
  1578. pGlyphPos[iGlyph].pgdf->pgb->aj,
  1579. pTempOutput,
  1580. SrcBytes,
  1581. DstBytes
  1582. );
  1583. }
  1584. iGlyph++;
  1585. GlyphPitchX += ulCharInc;
  1586. }
  1587. }
  1588. #endif