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.

1930 lines
78 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: fasttext.asm
  3. ;
  4. ; Copyright (c) 1992-1999 Microsoft Corporation
  5. ;-----------------------------------------------------------------------;
  6. ;-----------------------------------------------------------------------;
  7. ; VOID vFastText(GLYPHPOS * pGlyphPos, ULONG ulGlyphCount, PBYTE pTempBuffer,
  8. ; ULONG ulBufDelta, ULONG ulCharInc, DEVSURF * pdsurf,
  9. ; RECTL * prclText, RECTL * prclOpaque, INT iFgColor,
  10. ; INT iBgColor, ULONG fDrawFlags, RECTL * prclClip,
  11. ; RECTL * prclExtra, ULONG iTrgType);
  12. ; pGlyphPos -
  13. ; ulGlyphCount - # of glyphs to draw. Must never be 0.
  14. ; pTempBuffer -
  15. ; ulBufDelta -
  16. ; ulCharInc -
  17. ; pdsurf -
  18. ; prclText -
  19. ; prclOpaque -
  20. ; iFgColor -
  21. ; iBgColor -
  22. ; fDrawFlags -
  23. ; prclClip - array of clipping rectangles
  24. ; prclExtra - array of extra rectanlges to fill in foreground color
  25. ; iTrgType - 0 = VGA; 1 = DFB; 2 = NONE
  26. ;
  27. ; Performs accelerated proportional text drawing.
  28. ;
  29. ;-----------------------------------------------------------------------;
  30. ;
  31. ; Note: prclClip and prclExtra are null rectangle (yBottom=0) terminated
  32. ; arrays
  33. ;
  34. ; Note: Assumes the text rectangle has a positive height and width. Will
  35. ; not work properly if this is not the case.
  36. ;
  37. ; Note: The opaquing rectangle is assumed to match the text bounding
  38. ; rectangle exactly; prclOpaque is used only to determine whether or
  39. ; not opaquing is required.
  40. ;
  41. ; Note: For maximum performance, we should not bother to draw fully-
  42. ; clipped characters to the temp buffer.
  43. ;
  44. ; Note: We do not handle clipping or bank spanning in the very fast
  45. ; byte-wide-aligned-fixed-pitch console text. This would be an
  46. ; opportunity for somewhat faster console text performance.
  47. ;
  48. ;-----------------------------------------------------------------------;
  49. comment $
  50. The overall approach of this module is to draw the text into a system
  51. memory buffer, then copy the buffer to the screen a word at a time
  52. using write mode 3 so that no OUTs and a minimum of display memory reads
  53. are required.
  54. commend $
  55. .386
  56. ifndef DOS_PLATFORM
  57. .model small,c
  58. else
  59. ifdef STD_CALL
  60. .model small,c
  61. else
  62. .model small,pascal
  63. endif; STD_CALL
  64. endif; DOS_PLATFORM
  65. assume ds:FLAT,es:FLAT,ss:FLAT
  66. assume fs:nothing,gs:nothing
  67. .xlist
  68. include stdcall.inc
  69. include callconv.inc
  70. include gdii386.inc
  71. .list
  72. ;-----------------------------------------------------------------------;
  73. .data
  74. align 4
  75. ;-----------------------------------------------------------------------;
  76. ; Tables used to branch into glyph-drawing optimizations.
  77. ;
  78. ; Handles narrow (1-4 bytes wide) glyph drawing, for case where initial byte
  79. ; should be MOVed even if it's not aligned (intended for use in drawing the
  80. ; first glyph in a string). Table format is:
  81. ; Bits 3-2: dest width
  82. ; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  83. ; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  84. align 4
  85. MovInitialTableNarrow label dword
  86. dd exit_fast_text ;0 wide
  87. dd exit_fast_text ;0 wide
  88. dd exit_fast_text ;0 wide
  89. dd exit_fast_text ;0 wide
  90. dd mov_first_1_wide_rotated_need_last ;nonalign, 1 wide, need last
  91. dd mov_first_1_wide_unrotated ;aligned, 1 wide
  92. dd mov_first_1_wide_rotated_no_last ;nonalign, 1 wide, no last
  93. dd mov_first_1_wide_unrotated ;aligned, 1 wide
  94. dd mov_first_2_wide_rotated_need_last ;nonalign, 2 wide, need last
  95. dd mov_first_2_wide_unrotated ;aligned, 2 wide
  96. dd mov_first_2_wide_rotated_no_last ;nonalign, 2 wide, no last
  97. dd mov_first_2_wide_unrotated ;aligned, 2 wide
  98. dd mov_first_3_wide_rotated_need_last ;nonalign, 3 wide, need last
  99. dd mov_first_3_wide_unrotated ;aligned, 3 wide
  100. dd mov_first_3_wide_rotated_no_last ;nonalign, 3 wide, no last
  101. dd mov_first_3_wide_unrotated ;aligned, 3 wide
  102. dd mov_first_4_wide_rotated_need_last ;nonalign, 4 wide, need last
  103. dd mov_first_4_wide_unrotated ;aligned, 4 wide
  104. dd mov_first_4_wide_rotated_no_last ;nonalign, 4 wide, no last
  105. dd mov_first_4_wide_unrotated ;aligned, 4 wide
  106. ; Handles narrow (1-4 bytes wide) glyph drawing, for case where initial byte
  107. ; ORed if it's not aligned (intended for use in drawing all but the first glyph
  108. ; in a string). Table format is:
  109. ; Bits 3-2: dest width
  110. ; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  111. ; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  112. align 4
  113. OrInitialTableNarrow label dword
  114. dd exit_fast_text ;0 wide
  115. dd exit_fast_text ;0 wide
  116. dd exit_fast_text ;0 wide
  117. dd exit_fast_text ;0 wide
  118. dd or_first_1_wide_rotated_need_last ;nonalign, 1 wide, need last
  119. dd mov_first_1_wide_unrotated ;aligned, 1 wide
  120. dd or_first_1_wide_rotated_no_last ;nonalign, 1 wide, no last
  121. dd mov_first_1_wide_unrotated ;aligned, 1 wide
  122. dd or_first_2_wide_rotated_need_last ;nonalign, 2 wide, need last
  123. dd mov_first_2_wide_unrotated ;aligned, 2 wide
  124. dd or_first_2_wide_rotated_no_last ;nonalign, 2 wide, no last
  125. dd mov_first_2_wide_unrotated ;aligned, 2 wide
  126. dd or_first_3_wide_rotated_need_last ;nonalign, 3 wide, need last
  127. dd mov_first_3_wide_unrotated ;aligned, 3 wide
  128. dd or_first_3_wide_rotated_no_last ;nonalign, 3 wide, no last
  129. dd mov_first_3_wide_unrotated ;aligned, 3 wide
  130. dd or_first_4_wide_rotated_need_last ;nonalign, 4 wide, need last
  131. dd mov_first_4_wide_unrotated ;aligned, 4 wide
  132. dd or_first_4_wide_rotated_no_last ;nonalign, 4 wide, no last
  133. dd mov_first_4_wide_unrotated ;aligned, 4 wide
  134. ; Handles narrow (1-4 bytes wide) glyph drawing, for case where all bytes
  135. ; should be ORed (intended for use in drawing potentially overlapping glyphs).
  136. ; Table format is:
  137. ; Bits 3-2: dest width
  138. ; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  139. ; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  140. align 4
  141. OrAllTableNarrow label dword
  142. dd exit_fast_text ;0 wide
  143. dd exit_fast_text ;0 wide
  144. dd exit_fast_text ;0 wide
  145. dd exit_fast_text ;0 wide
  146. dd or_all_1_wide_rotated_need_last ;nonalign, 1 wide, need last
  147. dd or_all_1_wide_unrotated ;aligned, 1 wide
  148. dd or_all_1_wide_rotated_no_last ;nonalign, 1 wide, no last
  149. dd or_all_1_wide_unrotated ;aligned, 1 wide
  150. dd or_all_2_wide_rotated_need_last ;nonalign, 2 wide, need last
  151. dd or_all_2_wide_unrotated ;aligned, 2 wide
  152. dd or_all_2_wide_rotated_no_last ;nonalign, 2 wide, no last
  153. dd or_all_2_wide_unrotated ;aligned, 2 wide
  154. dd or_all_3_wide_rotated_need_last ;nonalign, 3 wide, need last
  155. dd or_all_3_wide_unrotated ;aligned, 3 wide
  156. dd or_all_3_wide_rotated_no_last ;nonalign, 3 wide, no last
  157. dd or_all_3_wide_unrotated ;aligned, 3 wide
  158. dd or_all_4_wide_rotated_need_last ;nonalign, 4 wide, need last
  159. dd or_all_4_wide_unrotated ;aligned, 4 wide
  160. dd or_all_4_wide_rotated_no_last ;nonalign, 4 wide, no last
  161. dd or_all_4_wide_unrotated ;aligned, 4 wide
  162. ; Handles arbitrarily wide glyph drawing, for case where initial byte should be
  163. ; MOVed even if it's not aligned (intended for use in drawing the first glyph
  164. ; in a string). Table format is:
  165. ; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  166. ; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  167. align 4
  168. MovInitialTableWide label dword
  169. dd mov_first_N_wide_rotated_need_last ;nonalign, need last
  170. dd mov_first_N_wide_unrotated ;aligned
  171. dd mov_first_N_wide_rotated_no_last ;nonalign, no last
  172. dd mov_first_N_wide_unrotated ;aligned
  173. ; Handles arbitrarily wide glyph drawing, for case where initial byte should be
  174. ; ORed if it's not aligned (intended for use in drawing all but the first glyph
  175. ; in a string). Table format is:
  176. ; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  177. ; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  178. align 4
  179. OrInitialTableWide label dword
  180. dd or_first_N_wide_rotated_need_last ;nonalign, need last
  181. dd mov_first_N_wide_unrotated ;aligned
  182. dd or_first_N_wide_rotated_no_last ;nonalign, no last
  183. dd mov_first_N_wide_unrotated ;aligned
  184. ; Handles arbitrarily wide glyph drawing, for case where all bytes should
  185. ; be ORed (intended for use in drawing potentially overlapping glyphs).
  186. ; Table format is:
  187. ; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
  188. ; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
  189. align 4
  190. OrAllTableWide label dword
  191. dd or_all_N_wide_rotated_need_last ;nonalign, need last
  192. dd or_all_N_wide_unrotated ;aligned
  193. dd or_all_N_wide_rotated_no_last ;nonalign, no last
  194. dd or_all_N_wide_unrotated ;aligned
  195. ; Vectors to entry points for drawing various types of text. '*' means works as
  196. ; is but could be acclerated with a custom scanning loop.
  197. align 4
  198. MasterTextTypeTable label dword ;tops aligned overlap fixed pitch
  199. dd draw_nf_ntb_o_to_temp_start ; N N N *
  200. dd draw_f_ntb_o_to_temp_start ; N N Y *
  201. dd draw_nf_ntb_o_to_temp_start ; N Y N
  202. dd draw_f_ntb_o_to_temp_start ; N Y Y
  203. dd draw_nf_tb_no_to_temp_start ; Y N N
  204. dd draw_f_tb_no_to_temp_start ; Y N Y
  205. dd draw_nf_ntb_o_to_temp_start ; Y Y N *
  206. dd draw_f_ntb_o_to_temp_start ; Y Y Y *
  207. dd 0;
  208. dd 0;
  209. dd 0;
  210. dd 0;
  211. dd 0;
  212. dd 0;
  213. dd 0;
  214. dd 0;
  215. ; Masks for clipping for the eight possible left and right edge alignments
  216. jOpaqueLeftMasks label byte
  217. db 0ffh,07fh,03fh,01fh,00fh,007h,003h,001h
  218. jOpaqueRightMasks label byte
  219. db 0ffh,080h,0c0h,0e0h,0f0h,0f8h,0fch,0feh
  220. dfbfill_jLeftMasks label dword
  221. db 0ffh,0ffh,0ffh,0ffh
  222. db 07fh,0ffh,0ffh,0ffh
  223. db 03fh,0ffh,0ffh,0ffh
  224. db 01fh,0ffh,0ffh,0ffh
  225. db 00fh,0ffh,0ffh,0ffh
  226. db 007h,0ffh,0ffh,0ffh
  227. db 003h,0ffh,0ffh,0ffh
  228. db 001h,0ffh,0ffh,0ffh
  229. db 000h,0ffh,0ffh,0ffh
  230. db 000h,07fh,0ffh,0ffh
  231. db 000h,03fh,0ffh,0ffh
  232. db 000h,01fh,0ffh,0ffh
  233. db 000h,00fh,0ffh,0ffh
  234. db 000h,007h,0ffh,0ffh
  235. db 000h,003h,0ffh,0ffh
  236. db 000h,001h,0ffh,0ffh
  237. db 000h,000h,0ffh,0ffh
  238. db 000h,000h,07fh,0ffh
  239. db 000h,000h,03fh,0ffh
  240. db 000h,000h,01fh,0ffh
  241. db 000h,000h,00fh,0ffh
  242. db 000h,000h,007h,0ffh
  243. db 000h,000h,003h,0ffh
  244. db 000h,000h,001h,0ffh
  245. db 000h,000h,000h,0ffh
  246. db 000h,000h,000h,07fh
  247. db 000h,000h,000h,03fh
  248. db 000h,000h,000h,01fh
  249. db 000h,000h,000h,00fh
  250. db 000h,000h,000h,007h
  251. db 000h,000h,000h,003h
  252. db 000h,000h,000h,001h
  253. dfbfill_jRightMasks label dword
  254. db 0ffh,0ffh,0ffh,0ffh
  255. db 080h,000h,000h,000h
  256. db 0c0h,000h,000h,000h
  257. db 0e0h,000h,000h,000h
  258. db 0f0h,000h,000h,000h
  259. db 0f8h,000h,000h,000h
  260. db 0fch,000h,000h,000h
  261. db 0feh,000h,000h,000h
  262. db 0ffh,000h,000h,000h
  263. db 0ffh,080h,000h,000h
  264. db 0ffh,0c0h,000h,000h
  265. db 0ffh,0e0h,000h,000h
  266. db 0ffh,0f0h,000h,000h
  267. db 0ffh,0f8h,000h,000h
  268. db 0ffh,0fch,000h,000h
  269. db 0ffh,0feh,000h,000h
  270. db 0ffh,0ffh,000h,000h
  271. db 0ffh,0ffh,080h,000h
  272. db 0ffh,0ffh,0c0h,000h
  273. db 0ffh,0ffh,0e0h,000h
  274. db 0ffh,0ffh,0f0h,000h
  275. db 0ffh,0ffh,0f8h,000h
  276. db 0ffh,0ffh,0fch,000h
  277. db 0ffh,0ffh,0feh,000h
  278. db 0ffh,0ffh,0ffh,000h
  279. db 0ffh,0ffh,0ffh,080h
  280. db 0ffh,0ffh,0ffh,0c0h
  281. db 0ffh,0ffh,0ffh,0e0h
  282. db 0ffh,0ffh,0ffh,0f0h
  283. db 0ffh,0ffh,0ffh,0f8h
  284. db 0ffh,0ffh,0ffh,0fch
  285. db 0ffh,0ffh,0ffh,0feh
  286. dfbfill_pfnScanHandlers label dword
  287. dd 0
  288. dd 0
  289. dd 0
  290. dd 0
  291. ;-----------------------------------------------------------------------;
  292. .code
  293. _TEXT$01 SEGMENT DWORD USE32 PUBLIC 'CODE'
  294. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  295. ;-----------------------------------------------------------------------;
  296. extrn draw_gray_nf_ntb_o_to_temp_start@28:NEAR
  297. extrn draw_gray_f_ntb_o_to_temp_start@28:NEAR
  298. cProc vFastText,52,<\
  299. uses esi edi ebx,\
  300. pGlyphPos:ptr,\
  301. ulGlyphCount:dword,\
  302. pTempBuffer:ptr,\
  303. ulBufDelta:dword,\
  304. ulCharInc:dword,\
  305. pdsurf:ptr,\
  306. prclText:ptr,\
  307. prclOpaque:ptr,\
  308. iFgColor:dword,\
  309. iBgColor:dword,\
  310. fDrawFlags:dword,\
  311. prclClip:dword,\
  312. prclExtra:dword>
  313. local ulGlyDelta:dword ;width per scan of source glyph, in bytes
  314. local ulWidthInBytes:dword ;width of glyph, in bytes
  315. local ulTmpWidthInBytes:dword ;working byte-width count
  316. local ulGlyphX:dword ;for fixed-pitch text, maintains the current
  317. ; glyph's left-edge X coordinate
  318. local pGlyphLoop:dword ;pointer to glyph-processing loop
  319. local ulTempLeft:dword ;X coordinate on screen of left edge of temp
  320. ; buffer
  321. local ulTempTop:dword ;Y coordinate on screen of top edge of temp
  322. ; buffer
  323. local ulLoopCount:dword ;general loop count storage
  324. local ulTmpSrcDelta:dword ;distance from end of one buffer text scan to
  325. ; start of next
  326. local ulTmpDstDelta:dword ;distance from end of one screen text scan to
  327. ; start of next
  328. local ulTopScan:dword ;top scan of dest text rect in current bank
  329. local ulBottomScan:dword ;bottom scan of dest text rect
  330. local ulNumScans:dword ;# of scans to draw
  331. local ulScreenDelta:dword ;scan-to-scan offset in screen
  332. local ulTextWidthInBytes:dword ;# of bytes across spanned by text
  333. local pScreen:dword ;pointer to first screen byte to which to draw
  334. local pfnEdgeVector:dword ;pointer to routine to draw any needed edges
  335. local pfnFirstOpaqVector:dword ;pointer to initial drawing routine
  336. ; called for opaque (either whole
  337. ; bytes, or edge(s) if no whole bytes)
  338. local ulWholeWidthInWords:dword ;# of whole words to copy
  339. local ulWholeWidthInWordsMinus1:dword ;# of whole words to copy, -1
  340. local ulOddByte:dword ;1 if odd byte in whole word copy
  341. local ulTextLeft:dword ;left edge of leftmost glyph
  342. local ulLeftMask:dword ;for opaque text, left edge mask for string
  343. local ulRightMask:dword ;for opaque text, right edge mask for string
  344. local ulScans:dword ;# of scans to draw
  345. local ulYOrigin:dword ;Y origin of text in string (all glyphs are at
  346. ; the same Y origin)
  347. local rclClippedBounds[16]:byte ;clipped destination rectangle;
  348. ; defined as "byte" due to assembler
  349. ; limitations
  350. local ulRectLeft:dword
  351. local ulRectRight:dword
  352. local pfnDrawScans:dword ;ptr to correct scan drawing function
  353. local pTempBufferSaved:dword
  354. local ulEdgeFlags:dword
  355. local ulBytesPerDstPlane:dword
  356. local ulLeftOffset:dword
  357. local pSrc:dword
  358. local pDst:dword
  359. local ulPlaneBit:dword
  360. TRAILING_PARTIAL equ 01h ;partial trailing dword should be copied
  361. LEADING_PARTIAL equ 02h ;partial leading dword should be copied
  362. ;-----------------------------------------------------------------------;
  363. ;
  364. ; For the moment, handle grayed text using the most general routine
  365. ; This means that we will be handing it back to the most general of
  366. ; of the C routines, namely
  367. ;
  368. ; VOID
  369. ; draw_gray_nf_ntb_o_to_temp_start(
  370. ; PGLYPHPOS pGlyphPos
  371. ; ULONG cGlyph
  372. ; PUCHAR pjTempBuffer
  373. ; ULONG BufferOffset
  374. ; ULONG ulBufferWidthInBytes
  375. ; ULONG ulCharInc
  376. ; ULONG ulTempTop
  377. ; )
  378. ;
  379. ; or for fixed pitch fonts
  380. ;
  381. ; VOID
  382. ; draw_gray_f_ntb_o_to_temp_start(
  383. ; PGLYPHPOS pGlyphPos
  384. ; ULONG cGlyph
  385. ; PUCHAR pjTempBuffer
  386. ; ULONG BufferOffset
  387. ; ULONG ulBufferWidthInBytes
  388. ; ULONG ulCharInc
  389. ; ULONG ulTempTop
  390. ; )
  391. ;
  392. ; Most of these parameters are in the arguments passed to vFastText.
  393. ; However, there are a couple that we must reconstruct. The first
  394. ; parameter to be pushed is ulTempTop. I look into the calling
  395. ; routine (vExpandAndCopyText) and find
  396. ;
  397. ; ulTempTop = prclText->top
  398. ; BufferOffset = 8 * floor(prclText->left/8)
  399. ;
  400. ; The factor of 8 is equal to the number of pixels contained in
  401. ; a DWORD. For monochrome text, this number would become 32
  402. ;
  403. ; The third argument to vFastText is pjTempBuffer which is equal to
  404. ;
  405. ; pjTempBuffer = pTempBuffer - ((prclText->left >> 3) & 3)
  406. ;
  407. ; (to draw_gray..) (input to vFastText)
  408. ;
  409. ;-----------------------------------------------------------------------;
  410. ;gray_text_test:
  411. mov edx,fDrawFlags ; Is this call for grayed text?
  412. test edx,8 ; test for ETO_GRAY in fDrawFlags
  413. jz monochrome_text ; if not go to monochrome code
  414. ;gray_text:
  415. mov ebx,prclText ; ebx = useful pointer to text rect
  416. push [ebx].yTop ; ulTempTop: 7'th argument
  417. push ulCharInc ; ulCharInc: 6'th argument
  418. push ulBufDelta ; dpDst: 5'th argument
  419. mov eax,[ebx].xLeft ; eax = prclText->left
  420. mov ecx,eax ; ecx = prclText->left
  421. and ecx,not 7 ; ecx = 8 * (prclText->left / 8)
  422. push ecx ; BufferOffset: 4'th argument
  423. sar eax,3 ; This is the part where we
  424. and eax,3 ; correct pjTempBuffer by subtracting
  425. neg eax ; off an additional factor (see above)
  426. add eax,pTempBuffer ; eax = pjTempBuffer[draw_gray..]
  427. push eax ; pjTempBuffer: 3'rd argument
  428. push ulGlyphCount ; cGlyph: 2'nd argument
  429. push pGlyphPos ; pGlyphPos: 1'st argument
  430. mov eax,draw_gray_f_ntb_o_to_temp_start@28
  431. test edx,1 ; fixed pitch ?
  432. jnz @f ; yes, eax is good, jump
  433. mov eax,draw_gray_nf_ntb_o_to_temp_start@28
  434. @@:
  435. call eax
  436. jmp exit_fast_text
  437. monochrome_text:
  438. cld
  439. ;-----------------------------------------------------------------------;
  440. ; Draws either a fixed or a non-fixed-pitch string to the temporary
  441. ; buffer. Assumes this is a horizontal string, so the origins of all glyphs
  442. ; are at the same Y coordinate. Draws leftmost glyph entirely with MOVs,
  443. ; even if it's not aligned, in order to ensure that the leftmost byte
  444. ; gets cleared when we're working with butted characters. For other
  445. ; non-aligned glyphs, leftmost byte is ORed, other bytes are MOVed.
  446. ;
  447. ; Input:
  448. ; pGlyphPos = pointer to array of GLYPHPOS structures to draw
  449. ; ulGlyphCount = # of glyphs to draw
  450. ; ulTempLeft = X coordinate on dest of left edge of temp buffer pointed
  451. ; to by pTempBuffer
  452. ; pTempBuffer = pointer to first byte (upper left corner) of
  453. ; temp buffer into which we're drawing. This should be
  454. ; dword-aligned with the destination
  455. ; ulBufDelta = destination scan-to-scan offset
  456. ; ulCharInc = offset from one glyph to next (fixed-pitch only)
  457. ; fDrawFlags = indicate the type of text to be drawn
  458. ; Temp buffer zeroed if text doesn't cover every single pixel
  459. ;
  460. ; Fixed-pitch means equal spacing between glyph positions, not that all
  461. ; glyphs butt together or equal spacing between upper left corners.
  462. ;-----------------------------------------------------------------------;
  463. mov ebx,prclText
  464. sub eax,eax
  465. ;-----------------------------------------------------------------------;
  466. ; Handle all cases other than 8-wide byte-aligned.
  467. ;-----------------------------------------------------------------------;
  468. general_handler:
  469. mov esi,pdsurf
  470. mov eax,[ebx].yTop
  471. mov ulTempTop,eax ;Y screen coordinate of top edge of temp buf
  472. mov eax,[ebx].xLeft
  473. and eax,not 7
  474. mov ulTempLeft,eax ;X screen coordinate of left edge of temp buf
  475. mov eax,[esi].dsurf_lNextScan
  476. mov ulScreenDelta,eax
  477. mov eax,fDrawFlags
  478. jmp MasterTextTypeTable[eax*4]
  479. ;-----------------------------------------------------------------------;
  480. ; Entry point for fixed-pitch | tops and bottoms aligned | no overlap.
  481. ; Sets up to draw first glyph.
  482. ;-----------------------------------------------------------------------;
  483. draw_f_tb_no_to_temp_start::
  484. mov ebx,pGlyphPos ;point to the first glyph to draw
  485. mov esi,[ebx].gp_pgdf ;point to glyph def
  486. mov edi,[ebx].gp_x ;dest X coordinate
  487. sub edi,ulTempLeft ;adjust relative to the left of the
  488. ; temp buffer (we assume the text is
  489. ; right at the top of the text rect
  490. ; and hence the buffer)
  491. mov ulGlyphX,edi ;remember where this glyph started
  492. mov esi,[esi].gdf_pgb ;point to glyph bits
  493. mov pGlyphLoop,offset draw_f_tb_no_to_temp_loop
  494. ;draw additional characters with this
  495. ; loop
  496. jmp short draw_to_temp_start_entry
  497. ;-----------------------------------------------------------------------;
  498. ; Entry point for non-fixed-pitch | tops and bottoms aligned | no overlap.
  499. ; Sets up to draw first glyph.
  500. ;-----------------------------------------------------------------------;
  501. draw_nf_tb_no_to_temp_start::
  502. mov ebx,pGlyphPos ;point to the first glyph to draw
  503. mov esi,[ebx].gp_pgdf ;point to glyph def
  504. mov edi,[ebx].gp_x ;dest X coordinate
  505. sub edi,ulTempLeft ;adjust relative to the left of the
  506. ; temp buffer
  507. mov esi,[esi].gdf_pgb ;point to glyph bits
  508. mov pGlyphLoop,offset draw_nf_tb_no_to_temp_loop
  509. ;draw additional characters with this
  510. ; loop
  511. draw_to_temp_start_entry::
  512. add edi,[esi].gb_x ;adjust to position of upper left glyph
  513. ; corner in dest
  514. mov ecx,edi
  515. shr edi,3 ;byte offset of first column of glyph
  516. ; offset of upper left of glyph in temp
  517. ; buffer
  518. add edi,pTempBuffer ;initial dest byte in temp buffer
  519. and ecx,111b ;bit alignment of upper left in temp
  520. ;calculate scan-to-scan glyph width
  521. mov ebx,[esi].gb_cx ;glyph width in pixels
  522. lea eax,[ebx+ecx+7]
  523. shr eax,3 ;# of dest bytes per scan
  524. add ebx,7
  525. shr ebx,3 ;# of source bytes per scan
  526. mov edx,ulBufDelta ;width of destination buffer in bytes
  527. cmp eax,4 ;do we have special case code for this
  528. ; dest width?
  529. ja short @F ;no, handle as general case
  530. ;yes, handle as special case
  531. cmp ebx,eax ;carry if more dest than source bytes
  532. ; (last source byte not needed)
  533. rcl eax,1 ;factor last source byte status in
  534. cmp cl,1 ;carry if aligned
  535. rcl eax,1 ;factor in alignment (aligned or not)
  536. mov ebx,[esi].gb_cy ;# of scans in glyph
  537. add esi,gb_aj ;point to the first glyph byte
  538. jmp MovInitialTableNarrow[eax*4]
  539. ;branch to draw the first glyph; never
  540. ; need to OR first glyph, because
  541. ; there's nothing there yet
  542. @@: ;too wide to special case
  543. mov ulWidthInBytes,eax ;# of bytes across dest
  544. cmp ebx,eax ;carry if more dest than source bytes
  545. ; (last source byte not needed)
  546. mov eax,0
  547. rcl eax,1 ;factor last source byte status in
  548. cmp cl,1 ;carry if aligned
  549. rcl eax,1 ;factor in alignment (aligned or not)
  550. mov ebx,[esi].gb_cx ;glyph width in pixels
  551. add ebx,7
  552. shr ebx,3 ;glyph width in bytes
  553. mov ulGlyDelta,ebx
  554. mov ebx,[esi].gb_cy ;# of scans in glyph
  555. add esi,gb_aj ;point to the first glyph byte
  556. jmp MovInitialTableWide[eax*4]
  557. ;branch to draw the first glyph; never
  558. ; need to OR first glyph, because
  559. ; there's nothing there yet
  560. ;-----------------------------------------------------------------------;
  561. ; Entry point for fixed-pitch | tops and bottoms not aligned | overlap.
  562. ; Sets up to draw first glyph.
  563. ;-----------------------------------------------------------------------;
  564. draw_f_ntb_o_to_temp_start::
  565. mov ebx,pGlyphPos ;point to the first glyph to draw
  566. mov pGlyphLoop,offset draw_f_ntb_o_to_temp_loop
  567. ;draw additional characters with this
  568. ; loop
  569. mov edi,[ebx].gp_x ;dest X coordinate
  570. mov esi,[ebx].gp_pgdf ;point to glyph def
  571. sub edi,ulTempLeft ;adjust relative to the left of the
  572. ; temp buffer
  573. mov ulGlyphX,edi ;remember where this glyph started
  574. mov esi,[esi].gdf_pgb ;point to glyph bits
  575. add edi,[esi].gb_x ;adjust to position of upper left glyph
  576. ; corner in dest
  577. mov ecx,edi
  578. shr edi,3 ;byte offset of first column of glyph
  579. ; offset of upper left of glyph in temp
  580. ; buffer
  581. jmp short draw_to_temp_start_entry2
  582. ;-----------------------------------------------------------------------;
  583. ; Entry point for non-fixed-pitch | tops and bottoms not aligned | overlap.
  584. ; Sets up to draw first glyph.
  585. ;-----------------------------------------------------------------------;
  586. draw_nf_ntb_o_to_temp_start::
  587. mov ebx,pGlyphPos ;point to the first glyph to draw
  588. mov pGlyphLoop,offset draw_nf_ntb_o_to_temp_loop
  589. ;draw additional characters with this
  590. ; loop
  591. mov edi,[ebx].gp_x ;dest X coordinate
  592. mov esi,[ebx].gp_pgdf ;point to glyph def
  593. sub edi,ulTempLeft ;adjust relative to the left of the
  594. ; temp buffer
  595. mov esi,[esi].gdf_pgb ;point to glyph bits
  596. add edi,[esi].gb_x ;adjust to position of upper left glyph
  597. ; corner in dest
  598. mov ecx,edi
  599. shr edi,3 ;byte offset of first column of glyph
  600. ; offset of upper left of glyph in temp
  601. ; buffer
  602. draw_to_temp_start_entry2::
  603. mov eax,[ebx].gp_y ;dest origin Y coordinate
  604. sub eax,ulTempTop ;coord of glyph origin in temp buffer
  605. mov ulYOrigin,eax ;remember the Y origin of all glyphs
  606. ; (necessary because glyph positions
  607. ; after first aren't set for fixed-
  608. ; pitch strings)
  609. add eax,[esi].gb_y ;adjust to position of upper left glyph
  610. ; corner in dest
  611. mul ulBufDelta ;offset in buffer of top glyph scan
  612. add eax,pTempBuffer ;initial dest byte
  613. add edi,eax
  614. and ecx,111b ;bit alignment of upper left in temp
  615. ;calculate scan-to-scan glyph width
  616. mov ebx,[esi].gb_cx ;glyph width in pixels
  617. lea eax,[ebx+ecx+7]
  618. shr eax,3 ;# of dest bytes per scan
  619. add ebx,7
  620. shr ebx,3 ;# of source bytes per scan
  621. mov edx,ulBufDelta ;width of destination buffer in bytes
  622. cmp eax,4 ;do we have special case code for this
  623. ; dest width?
  624. ja short @F ;no, handle as general case
  625. ;yes, handle as special case
  626. cmp ebx,eax ;carry if more dest than source bytes
  627. ; (last source byte not needed)
  628. rcl eax,1 ;factor last source byte status in
  629. cmp cl,1 ;carry if aligned
  630. rcl eax,1 ;factor in alignment (aligned or not)
  631. mov ebx,[esi].gb_cy ;# of scans in glyph
  632. add esi,gb_aj ;point to the first glyph byte
  633. jmp OrAllTableNarrow[eax*4] ;branch to draw the first glyph; OR all
  634. ; glyphs, because text may overlap
  635. @@: ;too wide to special case
  636. mov ulWidthInBytes,eax ;# of bytes across dest
  637. cmp ebx,eax ;carry if more dest than source bytes
  638. ; (last source byte not needed)
  639. mov eax,0
  640. rcl eax,1 ;factor last source byte status in
  641. cmp cl,1 ;carry if aligned
  642. rcl eax,1 ;factor in alignment (aligned or not)
  643. mov ebx,[esi].gb_cx ;glyph width in pixels
  644. add ebx,7
  645. shr ebx,3 ;glyph width in bytes
  646. mov ulGlyDelta,ebx
  647. mov ebx,[esi].gb_cy ;# of scans in glyph
  648. add esi,gb_aj ;point to the first glyph byte
  649. jmp OrAllTableWide[eax*4] ;branch to draw the first glyph; OR all
  650. ; glyphs, because text may overlap
  651. ;-----------------------------------------------------------------------;
  652. ; Loop to draw all fixed-pitch | tops and bottoms aligned | no overlap
  653. ; glyphs after first.
  654. ;-----------------------------------------------------------------------;
  655. draw_f_tb_no_to_temp_loop::
  656. dec ulGlyphCount ;any more glyphs to draw?
  657. jz glyphs_are_done ;no, done
  658. mov ebx,pGlyphPos
  659. add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one
  660. mov pGlyphPos,ebx ; we're going to draw this time)
  661. mov esi,[ebx].gp_pgdf ;point to glyph def
  662. mov edi,ulGlyphX ;last glyph's dest X start in temp buf
  663. add edi,ulCharInc ;this glyph's dest X start in temp buf
  664. mov ulGlyphX,edi ;remember for next glyph
  665. mov esi,[esi].gdf_pgb ;point to glyph bits
  666. jmp short draw_to_temp_loop_entry
  667. ;-----------------------------------------------------------------------;
  668. ; Loop to draw all non-fixed-pitch | tops and bottoms aligned | no overlap
  669. ; glyphs after first.
  670. ;-----------------------------------------------------------------------;
  671. draw_nf_tb_no_to_temp_loop::
  672. dec ulGlyphCount ;any more glyphs to draw?
  673. jz glyphs_are_done ;no, done
  674. mov ebx,pGlyphPos
  675. add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one we're
  676. mov pGlyphPos,ebx ; going to draw this time)
  677. mov esi,[ebx].gp_pgdf ;point to glyph def
  678. mov edi,[ebx].gp_x ;dest X coordinate
  679. mov esi,[esi].gdf_pgb ;point to glyph bits
  680. sub edi,ulTempLeft ;adjust relative to the left edge of
  681. ; the temp buffer
  682. draw_to_temp_loop_entry::
  683. add edi,[esi].gb_x ;adjust to position of upper left glyph
  684. ; corner in dest
  685. mov ecx,edi ;pixel X coordinate in temp buffer
  686. shr edi,3 ;byte offset of first column = dest
  687. ; offset of upper left of glyph in temp
  688. ; buffer
  689. add edi,pTempBuffer ;initial dest byte
  690. and ecx,111b ;bit alignment of upper left in temp
  691. ;calculate scan-to-scan glyph width
  692. mov ebx,[esi].gb_cx ;glyph width in pixels
  693. lea eax,[ebx+ecx+7]
  694. shr eax,3 ;# of dest bytes to copy to per scan
  695. add ebx,7
  696. shr ebx,3 ;# of source bytes to copy from per
  697. ; scan
  698. mov edx,ulBufDelta ;width of destination buffer in bytes
  699. cmp eax,4 ;do we have special case code for this
  700. ; dest width?
  701. ja short @F ;no, handle as general case
  702. ;yes, handle as special case
  703. cmp ebx,eax ;carry if more dest than source bytes
  704. ; (last source byte not needed)
  705. rcl eax,1 ;factor last source byte status in
  706. cmp cl,1 ;carry if aligned
  707. rcl eax,1 ;factor in alignment (aligned or not)
  708. mov ebx,[esi].gb_cy ;# of scans in glyph
  709. add esi,gb_aj ;point to the first glyph byte
  710. jmp OrInitialTableNarrow[eax*4] ;branch to draw the first glyph;
  711. ; need to OR the 1st byte if
  712. ; non-aligned to avoid overwriting
  713. ; what's already there
  714. @@: ;too wide to special case
  715. mov ulWidthInBytes,eax ;# of bytes across dest
  716. cmp ebx,eax ;carry if more dest than source bytes
  717. ; (last source byte not needed)
  718. mov eax,0
  719. rcl eax,1 ;factor last source byte status in
  720. cmp cl,1 ;carry if aligned
  721. rcl eax,1 ;factor in alignment (aligned or not)
  722. mov ebx,[esi].gb_cx ;glyph width in pixels
  723. add ebx,7
  724. shr ebx,3 ;glyph width in bytes
  725. mov ulGlyDelta,ebx
  726. mov ebx,[esi].gb_cy ;# of scans in glyph
  727. add esi,gb_aj ;point to the first glyph byte
  728. jmp OrInitialTableWide[eax*4] ;branch to draw the next glyph;
  729. ; need to OR the 1st byte if
  730. ; non-aligned to avoid overwriting
  731. ; what's already there
  732. ;-----------------------------------------------------------------------;
  733. ; Loop to draw all fixed-pitch | tops and bottoms not aligned | overlap
  734. ; glyphs after first.
  735. ;-----------------------------------------------------------------------;
  736. draw_f_ntb_o_to_temp_loop::
  737. dec ulGlyphCount ;any more glyphs to draw?
  738. jz glyphs_are_done ;no, done
  739. mov ebx,pGlyphPos
  740. add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one we're
  741. mov pGlyphPos,ebx ; going to draw this time)
  742. mov esi,[ebx].gp_pgdf ;point to glyph def
  743. mov edi,ulGlyphX ;last glyph's dest X start in temp buf
  744. add edi,ulCharInc ;this glyph's dest X start in temp buf
  745. mov ulGlyphX,edi ;remember for next glyph
  746. mov esi,[esi].gdf_pgb ;point to glyph bits
  747. mov eax,ulYOrigin ;dest Y coordinate
  748. jmp short draw_to_temp_loop_entry2
  749. ;-----------------------------------------------------------------------;
  750. ; Loop to draw all non-fixed-pitch | tops and bottoms not aligned | overlap
  751. ; glyphs after first.
  752. ;-----------------------------------------------------------------------;
  753. draw_nf_ntb_o_to_temp_loop::
  754. dec ulGlyphCount ;any more glyphs to draw?
  755. jz glyphs_are_done ;no, done
  756. mov ebx,pGlyphPos
  757. add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one we're
  758. mov pGlyphPos,ebx ; going to draw this time)
  759. mov esi,[ebx].gp_pgdf ;point to glyph def
  760. mov edi,[ebx].gp_x ;dest X coordinate
  761. mov esi,[esi].gdf_pgb ;point to glyph bits
  762. sub edi,ulTempLeft ;adjust relative to the left edge of
  763. ; the temp buffer
  764. mov eax,[ebx].gp_y ;dest origin Y coordinate
  765. sub eax,ulTempTop ;coord of glyph origin in temp buffer
  766. draw_to_temp_loop_entry2::
  767. add edi,[esi].gb_x ;adjust to position of upper left glyph
  768. ; corner in dest
  769. mov ecx,edi ;pixel X coordinate in temp buffer
  770. shr edi,3 ;byte offset of first column = dest
  771. ; offset of upper left of glyph in temp
  772. ; buffer
  773. add eax,[esi].gb_y ;adjust to position of upper left glyph
  774. ; corner in dest
  775. mul ulBufDelta ;offset in buffer of top glyph scan
  776. add eax,pTempBuffer ;initial dest byte
  777. add edi,eax
  778. and ecx,111b ;bit alignment of upper left in temp
  779. ;calculate scan-to-scan glyph width
  780. mov ebx,[esi].gb_cx ;glyph width in pixels
  781. lea eax,[ebx+ecx+7]
  782. shr eax,3 ;# of dest bytes to copy to per scan
  783. add ebx,7
  784. shr ebx,3 ;# of source bytes to copy from per
  785. ; scan
  786. mov edx,ulBufDelta ;width of destination buffer in bytes
  787. cmp eax,4 ;do we have special case code for this
  788. ; dest width?
  789. ja short @F ;no, handle as general case
  790. ;yes, handle as special case
  791. cmp ebx,eax ;carry if more dest than source bytes
  792. ; (last source byte not needed)
  793. rcl eax,1 ;factor last source byte status in
  794. cmp cl,1 ;carry if aligned
  795. rcl eax,1 ;factor in alignment (aligned or not)
  796. mov ebx,[esi].gb_cy ;# of scans in glyph
  797. add esi,gb_aj ;point to the first glyph byte
  798. jmp OrAllTableNarrow[eax*4] ;branch to draw the next glyph
  799. @@: ;too wide to special case
  800. mov ulWidthInBytes,eax ;# of bytes across dest
  801. cmp ebx,eax ;carry if more dest than source bytes
  802. ; (last source byte not needed)
  803. mov eax,0
  804. rcl eax,1 ;factor last source byte status in
  805. cmp cl,1 ;carry if aligned
  806. rcl eax,1 ;factor in alignment (aligned or not)
  807. mov ebx,[esi].gb_cx ;glyph width in pixels
  808. add ebx,7
  809. shr ebx,3 ;glyph width in bytes
  810. mov ulGlyDelta,ebx
  811. mov ebx,[esi].gb_cy ;# of scans in glyph
  812. add esi,gb_aj ;point to the first glyph byte
  813. jmp OrAllTableWide[eax*4] ;branch to draw the next glyph
  814. ;-----------------------------------------------------------------------;
  815. ; Routines to draw all scans of a single glyph into the temp buffer,
  816. ; optimized for the following cases:
  817. ;
  818. ; 1 to 4 byte-wide destination rectangles for each of:
  819. ; No rotation needed
  820. ; Rotation needed, same # of source as dest bytes needed
  821. ; Rotation needed, one less source than dest bytes needed
  822. ;
  823. ; Additionally, the three cases are handled for 5 and wider cases by a
  824. ; general routine for each case.
  825. ;
  826. ; If rotation is needed, there are three sorts of routines:
  827. ;
  828. ; 1) The leftmost byte is MOVed, to initialize the byte. Succeeding bytes are
  829. ; MOVed. This is generally used for the leftmost glyph of a string.
  830. ; 2) The leftmost byte is ORed into the existing byte. Succeeding bytes are
  831. ; MOVed. This is generally used after the leftmost glyph, because this may
  832. ; not be the first data written to that byte.
  833. ; 3) All bytes are ORed. This is for drawing when characters might overlap.
  834. ;
  835. ; If rotation is not needed, there are two sorts of routines:
  836. ;
  837. ; 1) The leftmost byte is MOVed, to initialize the byte. Succeeding bytes are
  838. ; MOVed. This is generally used for the leftmost glyph of a string.
  839. ; 2) All bytes are ORed. This is for drawing when characters might overlap.
  840. ;
  841. ; On entry:
  842. ; EBX = # of scans to copy
  843. ; CL = right rotation
  844. ; EDX = ulBufDelta = width per scan of destination buffer, in bytes
  845. ; ESI = pointer to first glyph byte
  846. ; EDI = pointer to first dest buffer byte
  847. ; DF = cleared
  848. ; ulGlyDelta = width per scan of source glyph, in bytes (wide case only)
  849. ; ulWidthInBytes = width of glyph, in bytes (required only for 5 and
  850. ; wider cases)
  851. ;
  852. ; On exit:
  853. ; Any or all of EAX, EBX, ECX, EDX, ESI, and EDI may be trashed.
  854. ;-----------------------------------------------------------------------;
  855. ; OR first byte, 1 byte wide dest, rotated.
  856. ;-----------------------------------------------------------------------;
  857. or_all_1_wide_rotated_need_last::
  858. or_all_1_wide_rotated_no_last::
  859. or_first_1_wide_rotated_need_last::
  860. or_first_1_wide_rotated_no_last::
  861. or_first_1_wide_rotated_loop::
  862. mov ch,[esi]
  863. inc esi
  864. shr ch,cl
  865. or [edi],ch
  866. add edi,edx
  867. dec ebx
  868. jnz or_first_1_wide_rotated_loop
  869. jmp pGlyphLoop
  870. ;-----------------------------------------------------------------------;
  871. ; MOV first byte, 1 byte wide dest, rotated.
  872. ;-----------------------------------------------------------------------;
  873. mov_first_1_wide_rotated_need_last::
  874. mov_first_1_wide_rotated_no_last::
  875. mov_first_1_wide_rotated_loop::
  876. mov ch,[esi]
  877. inc esi
  878. shr ch,cl
  879. mov [edi],ch
  880. add edi,edx
  881. dec ebx
  882. jnz mov_first_1_wide_rotated_loop
  883. jmp pGlyphLoop
  884. ;-----------------------------------------------------------------------;
  885. ; MOV first byte, 1 byte wide dest, unrotated.
  886. ;-----------------------------------------------------------------------;
  887. mov_first_1_wide_unrotated::
  888. mov_first_1_wide_unrotated_loop::
  889. mov al,[esi]
  890. inc esi
  891. mov [edi],al
  892. add edi,edx
  893. dec ebx
  894. jnz mov_first_1_wide_unrotated_loop
  895. jmp pGlyphLoop
  896. ;-----------------------------------------------------------------------;
  897. ; OR all bytes, 1 byte wide dest, unrotated.
  898. ;-----------------------------------------------------------------------;
  899. or_all_1_wide_unrotated::
  900. or_all_1_wide_unrotated_loop::
  901. mov al,[esi]
  902. inc esi
  903. or [edi],al
  904. add edi,edx
  905. dec ebx
  906. jnz or_all_1_wide_unrotated_loop
  907. jmp pGlyphLoop
  908. ;-----------------------------------------------------------------------;
  909. ; OR first byte, 2 bytes wide dest, rotated, need final source byte.
  910. ;-----------------------------------------------------------------------;
  911. or_first_2_wide_rotated_need_last::
  912. or_first_2_wide_rotated_need_loop::
  913. mov ax,[esi]
  914. add esi,2
  915. ror ax,cl
  916. or [edi],al
  917. mov [edi+1],ah
  918. add edi,edx
  919. dec ebx
  920. jnz or_first_2_wide_rotated_need_loop
  921. jmp pGlyphLoop
  922. ;-----------------------------------------------------------------------;
  923. ; OR all bytes, 2 bytes wide dest, rotated, need final source byte.
  924. ;-----------------------------------------------------------------------;
  925. or_all_2_wide_rotated_need_last::
  926. or_all_2_wide_rotated_need_loop::
  927. mov ax,[esi]
  928. add esi,2
  929. ror ax,cl
  930. or [edi],ax
  931. add edi,edx
  932. dec ebx
  933. jnz or_all_2_wide_rotated_need_loop
  934. jmp pGlyphLoop
  935. ;-----------------------------------------------------------------------;
  936. ; MOV first byte, 2 bytes wide dest, rotated, need final source byte.
  937. ;-----------------------------------------------------------------------;
  938. mov_first_2_wide_rotated_need_last::
  939. mov_first_2_wide_rotated_need_loop::
  940. mov ax,[esi]
  941. add esi,2
  942. ror ax,cl
  943. mov [edi],ax
  944. add edi,edx
  945. dec ebx
  946. jnz mov_first_2_wide_rotated_need_loop
  947. jmp pGlyphLoop
  948. ;-----------------------------------------------------------------------;
  949. ; OR first byte, 2 bytes wide dest, rotated, don't need final source byte.
  950. ;-----------------------------------------------------------------------;
  951. or_first_2_wide_rotated_no_last::
  952. or_first_2_wide_rotated_loop::
  953. sub eax,eax
  954. mov ah,[esi]
  955. inc esi
  956. shr eax,cl
  957. or [edi],ah
  958. mov [edi+1],al
  959. add edi,edx
  960. dec ebx
  961. jnz or_first_2_wide_rotated_loop
  962. jmp pGlyphLoop
  963. ;-----------------------------------------------------------------------;
  964. ; OR all bytes, 2 bytes wide dest, rotated, don't need final source byte.
  965. ;-----------------------------------------------------------------------;
  966. or_all_2_wide_rotated_no_last::
  967. or_all_2_wide_rotated_loop::
  968. sub eax,eax
  969. mov al,[esi]
  970. inc esi
  971. ror ax,cl
  972. or [edi],ax
  973. add edi,edx
  974. dec ebx
  975. jnz or_all_2_wide_rotated_loop
  976. jmp pGlyphLoop
  977. ;-----------------------------------------------------------------------;
  978. ; MOV first byte, 2 bytes wide dest, rotated, don't need final source byte.
  979. ;-----------------------------------------------------------------------;
  980. mov_first_2_wide_rotated_no_last::
  981. mov_first_2_wide_rotated_loop::
  982. sub eax,eax
  983. mov al,[esi]
  984. inc esi
  985. ror ax,cl
  986. mov [edi],ax
  987. add edi,edx
  988. dec ebx
  989. jnz mov_first_2_wide_rotated_loop
  990. jmp pGlyphLoop
  991. ;-----------------------------------------------------------------------;
  992. ; MOV first byte, 2 bytes wide dest, unrotated.
  993. ;-----------------------------------------------------------------------;
  994. mov_first_2_wide_unrotated::
  995. mov_first_2_wide_unrotated_loop::
  996. mov ax,[esi]
  997. add esi,2
  998. mov [edi],ax
  999. add edi,edx
  1000. dec ebx
  1001. jnz mov_first_2_wide_unrotated_loop
  1002. jmp pGlyphLoop
  1003. ;-----------------------------------------------------------------------;
  1004. ; OR all bytes, 2 bytes wide dest, unrotated.
  1005. ;-----------------------------------------------------------------------;
  1006. or_all_2_wide_unrotated::
  1007. or_all_2_wide_unrotated_loop::
  1008. mov ax,[esi]
  1009. add esi,2
  1010. or [edi],ax
  1011. add edi,edx
  1012. dec ebx
  1013. jnz or_all_2_wide_unrotated_loop
  1014. jmp pGlyphLoop
  1015. ;-----------------------------------------------------------------------;
  1016. ; OR first byte, 3 bytes wide dest, rotated, need final source byte.
  1017. ;-----------------------------------------------------------------------;
  1018. or_first_3_wide_rotated_need_last::
  1019. @@:
  1020. mov al,[esi]
  1021. shr al,cl
  1022. or [edi],al
  1023. mov ax,[esi]
  1024. ror ax,cl
  1025. mov [edi+1],ah
  1026. mov ax,[esi+1]
  1027. add esi,3
  1028. ror ax,cl
  1029. mov [edi+2],ah
  1030. add edi,edx
  1031. dec ebx
  1032. jnz @B
  1033. jmp pGlyphLoop
  1034. ;-----------------------------------------------------------------------;
  1035. ; OR first byte, 3 bytes wide dest, rotated, need final source byte.
  1036. ;-----------------------------------------------------------------------;
  1037. or_all_3_wide_rotated_need_last::
  1038. @@:
  1039. mov al,[esi]
  1040. shr al,cl
  1041. or [edi],al
  1042. mov ax,[esi]
  1043. ror ax,cl
  1044. or [edi+1],ah
  1045. mov ax,[esi+1]
  1046. add esi,3
  1047. ror ax,cl
  1048. or [edi+2],ah
  1049. add edi,edx
  1050. dec ebx
  1051. jnz @B
  1052. jmp pGlyphLoop
  1053. ;-----------------------------------------------------------------------;
  1054. ; MOV first byte, 3 bytes wide dest, rotated, need final source byte.
  1055. ;-----------------------------------------------------------------------;
  1056. mov_first_3_wide_rotated_need_last::
  1057. @@:
  1058. mov al,[esi]
  1059. shr al,cl
  1060. mov [edi],al
  1061. mov ax,[esi]
  1062. ror ax,cl
  1063. mov [edi+1],ah
  1064. mov ax,[esi+1]
  1065. add esi,3
  1066. ror ax,cl
  1067. mov [edi+2],ah
  1068. add edi,edx
  1069. dec ebx
  1070. jnz @B
  1071. jmp pGlyphLoop
  1072. ;-----------------------------------------------------------------------;
  1073. ; OR first byte, 3 bytes wide dest, rotated, don't need final source byte.
  1074. ;-----------------------------------------------------------------------;
  1075. or_first_3_wide_rotated_no_last::
  1076. neg cl
  1077. and cl,111b ;convert from right shift to left shift
  1078. @@:
  1079. sub eax,eax
  1080. mov ax,[esi]
  1081. add esi,2
  1082. xchg ah,al
  1083. shl eax,cl
  1084. mov [edi+1],ah
  1085. mov [edi+2],al
  1086. shr eax,16
  1087. or [edi],al
  1088. add edi,edx
  1089. dec ebx
  1090. jnz @B
  1091. jmp pGlyphLoop
  1092. ;-----------------------------------------------------------------------;
  1093. ; OR all bytes, 3 bytes wide dest, rotated, don't need final source byte.
  1094. ;-----------------------------------------------------------------------;
  1095. or_all_3_wide_rotated_no_last::
  1096. neg cl
  1097. and cl,111b ;convert from right shift to left shift
  1098. @@:
  1099. sub eax,eax
  1100. mov ax,[esi]
  1101. add esi,2
  1102. xchg ah,al
  1103. shl eax,cl
  1104. xchg ah,al
  1105. or [edi+1],ax
  1106. shr eax,16
  1107. or [edi],al
  1108. add edi,edx
  1109. dec ebx
  1110. jnz @B
  1111. jmp pGlyphLoop
  1112. ;-----------------------------------------------------------------------;
  1113. ; MOV first byte, 3 bytes wide dest, rotated, don't need final source byte.
  1114. ;-----------------------------------------------------------------------;
  1115. mov_first_3_wide_rotated_no_last::
  1116. neg cl
  1117. and cl,111b ;convert from right shift to left shift
  1118. @@:
  1119. sub eax,eax
  1120. mov ax,[esi]
  1121. add esi,2
  1122. xchg ah,al
  1123. shl eax,cl
  1124. mov [edi+1],ah
  1125. mov [edi+2],al
  1126. shr eax,16
  1127. mov [edi],al
  1128. add edi,edx
  1129. dec ebx
  1130. jnz @B
  1131. jmp pGlyphLoop
  1132. ;-----------------------------------------------------------------------;
  1133. ; MOV first byte, 3 bytes wide dest, unrotated.
  1134. ;-----------------------------------------------------------------------;
  1135. mov_first_3_wide_unrotated::
  1136. @@:
  1137. mov ax,[esi]
  1138. mov [edi],ax
  1139. mov al,[esi+2]
  1140. add esi,3
  1141. mov [edi+2],al
  1142. add edi,edx
  1143. dec ebx
  1144. jnz @B
  1145. jmp pGlyphLoop
  1146. ;-----------------------------------------------------------------------;
  1147. ; OR all bytes, 3 bytes wide dest, unrotated.
  1148. ;-----------------------------------------------------------------------;
  1149. or_all_3_wide_unrotated::
  1150. @@:
  1151. mov ax,[esi]
  1152. or [edi],ax
  1153. mov al,[esi+2]
  1154. add esi,3
  1155. or [edi+2],al
  1156. add edi,edx
  1157. dec ebx
  1158. jnz @B
  1159. jmp pGlyphLoop
  1160. ;-----------------------------------------------------------------------;
  1161. ; OR first byte, 4 bytes wide dest, rotated, need final source byte.
  1162. ;-----------------------------------------------------------------------;
  1163. or_first_4_wide_rotated_need_last::
  1164. @@:
  1165. mov eax,[esi]
  1166. add esi,4
  1167. xchg ah,al
  1168. ror eax,16
  1169. xchg ah,al
  1170. shr eax,cl
  1171. xchg ah,al
  1172. mov [edi+2],ax
  1173. shr eax,16
  1174. mov [edi+1],al
  1175. or [edi],ah
  1176. add edi,edx
  1177. dec ebx
  1178. jnz @B
  1179. jmp pGlyphLoop
  1180. ;-----------------------------------------------------------------------;
  1181. ; OR all bytes, 4 bytes wide dest, rotated, need final source byte.
  1182. ;-----------------------------------------------------------------------;
  1183. or_all_4_wide_rotated_need_last::
  1184. @@:
  1185. mov eax,[esi]
  1186. add esi,4
  1187. xchg ah,al
  1188. ror eax,16
  1189. xchg ah,al
  1190. shr eax,cl
  1191. xchg ah,al
  1192. ror eax,16
  1193. xchg al,ah
  1194. or [edi],eax
  1195. add edi,edx
  1196. dec ebx
  1197. jnz @B
  1198. jmp pGlyphLoop
  1199. ;-----------------------------------------------------------------------;
  1200. ; MOV first byte, 4 bytes wide dest, rotated, need final source byte.
  1201. ;-----------------------------------------------------------------------;
  1202. mov_first_4_wide_rotated_need_last::
  1203. @@:
  1204. mov eax,[esi]
  1205. add esi,4
  1206. xchg ah,al
  1207. ror eax,16
  1208. xchg ah,al
  1209. shr eax,cl
  1210. xchg ah,al
  1211. ror eax,16
  1212. xchg ah,al
  1213. mov [edi],eax
  1214. add edi,edx
  1215. dec ebx
  1216. jnz @B
  1217. jmp pGlyphLoop
  1218. ;-----------------------------------------------------------------------;
  1219. ; OR first byte, 4 bytes wide dest, rotated, don't need final source byte.
  1220. ;-----------------------------------------------------------------------;
  1221. or_first_4_wide_rotated_no_last::
  1222. @@:
  1223. mov ax,[esi]
  1224. xchg ah,al
  1225. shl eax,16
  1226. mov ah,[esi+2]
  1227. add esi,3
  1228. shr eax,cl
  1229. xchg ah,al
  1230. mov [edi+2],ax
  1231. shr eax,16
  1232. mov [edi+1],al
  1233. or [edi],ah
  1234. add edi,edx
  1235. dec ebx
  1236. jnz @B
  1237. jmp pGlyphLoop
  1238. ;-----------------------------------------------------------------------;
  1239. ; OR all bytes, 4 bytes wide dest, rotated, don't need final source byte.
  1240. ;-----------------------------------------------------------------------;
  1241. or_all_4_wide_rotated_no_last::
  1242. @@:
  1243. mov ax,[esi]
  1244. xchg ah,al
  1245. shl eax,16
  1246. mov ah,[esi+2]
  1247. add esi,3
  1248. shr eax,cl
  1249. xchg ah,al
  1250. ror eax,16
  1251. xchg ah,al
  1252. or [edi],eax
  1253. add edi,edx
  1254. dec ebx
  1255. jnz @B
  1256. jmp pGlyphLoop
  1257. ;-----------------------------------------------------------------------;
  1258. ; MOV first byte, 4 bytes wide dest, rotated, don't need final source byte.
  1259. ;-----------------------------------------------------------------------;
  1260. mov_first_4_wide_rotated_no_last::
  1261. @@:
  1262. mov ax,[esi]
  1263. xchg ah,al
  1264. shl eax,16
  1265. mov ah,[esi+2]
  1266. add esi,3
  1267. shr eax,cl
  1268. xchg ah,al
  1269. ror eax,16
  1270. xchg ah,al
  1271. mov [edi],eax
  1272. add edi,edx
  1273. dec ebx
  1274. jnz @B
  1275. jmp pGlyphLoop
  1276. ;-----------------------------------------------------------------------;
  1277. ; MOV first byte, 4 bytes wide dest, unrotated.
  1278. ;-----------------------------------------------------------------------;
  1279. mov_first_4_wide_unrotated::
  1280. @@:
  1281. mov eax,[esi]
  1282. add esi,4
  1283. mov [edi],eax
  1284. add edi,edx
  1285. dec ebx
  1286. jnz @B
  1287. jmp pGlyphLoop
  1288. ;-----------------------------------------------------------------------;
  1289. ; OR all bytes, 4 bytes wide dest, unrotated.
  1290. ;-----------------------------------------------------------------------;
  1291. or_all_4_wide_unrotated::
  1292. @@:
  1293. mov eax,[esi]
  1294. add esi,4
  1295. or [edi],eax
  1296. add edi,edx
  1297. dec ebx
  1298. jnz @B
  1299. jmp pGlyphLoop
  1300. ;-----------------------------------------------------------------------;
  1301. ; OR first byte, n bytes wide dest, rotated, need final source byte.
  1302. ;-----------------------------------------------------------------------;
  1303. or_first_N_wide_rotated_need_last::
  1304. mov eax,ulWidthInBytes
  1305. mov edx,ulBufDelta
  1306. sub edx,eax
  1307. mov ulTmpDstDelta,edx
  1308. dec eax ;source doesn't advance after first byte, and
  1309. ; we do the first byte outside the loop
  1310. mov edx,ulGlyDelta
  1311. sub edx,eax
  1312. mov ulTmpSrcDelta,edx
  1313. mov ulTmpWidthInBytes,eax
  1314. ofNwrnl_scan_loop:
  1315. mov al,[esi] ;do the initial, ORed byte separately
  1316. shr al,cl
  1317. or [edi],al
  1318. inc edi
  1319. mov edx,ulTmpWidthInBytes
  1320. @@:
  1321. mov ax,[esi]
  1322. inc esi
  1323. ror ax,cl
  1324. mov [edi],ah
  1325. inc edi
  1326. dec edx
  1327. jnz @B
  1328. add esi,ulTmpSrcDelta
  1329. add edi,ulTmpDstDelta
  1330. dec ebx
  1331. jnz ofNwrnl_scan_loop
  1332. jmp pGlyphLoop
  1333. ;-----------------------------------------------------------------------;
  1334. ; OR all bytes, n bytes wide dest, rotated, need final source byte.
  1335. ;-----------------------------------------------------------------------;
  1336. or_all_N_wide_rotated_need_last::
  1337. mov eax,ulWidthInBytes
  1338. mov edx,ulBufDelta
  1339. sub edx,eax
  1340. mov ulTmpDstDelta,edx
  1341. dec eax ;source doesn't advance after first byte, and
  1342. ; we do the first byte outside the loop
  1343. mov edx,ulGlyDelta
  1344. sub edx,eax
  1345. mov ulTmpSrcDelta,edx
  1346. mov ulTmpWidthInBytes,eax
  1347. oaNwrnl_scan_loop:
  1348. mov al,[esi] ;do the initial, ORed byte separately
  1349. shr al,cl
  1350. or [edi],al
  1351. inc edi
  1352. mov edx,ulTmpWidthInBytes
  1353. @@:
  1354. mov ax,[esi]
  1355. inc esi
  1356. ror ax,cl
  1357. or [edi],ah
  1358. inc edi
  1359. dec edx
  1360. jnz @B
  1361. add esi,ulTmpSrcDelta
  1362. add edi,ulTmpDstDelta
  1363. dec ebx
  1364. jnz oaNwrnl_scan_loop
  1365. jmp pGlyphLoop
  1366. ;-----------------------------------------------------------------------;
  1367. ; MOV first byte, n bytes wide dest, rotated, need final source byte.
  1368. ;-----------------------------------------------------------------------;
  1369. mov_first_N_wide_rotated_need_last::
  1370. mov eax,ulWidthInBytes
  1371. mov edx,ulBufDelta
  1372. sub edx,eax
  1373. mov ulTmpDstDelta,edx
  1374. mov eax,ulWidthInBytes
  1375. dec eax ;source doesn't advance after first byte, and
  1376. ; we do the first byte outside the loop
  1377. mov edx,ulGlyDelta
  1378. sub edx,eax
  1379. mov ulTmpSrcDelta,edx
  1380. mov ulTmpWidthInBytes,eax
  1381. mfNwrnl_scan_loop:
  1382. mov al,[esi] ;do the initial byte separately
  1383. shr al,cl
  1384. mov [edi],al
  1385. inc edi
  1386. mov edx,ulTmpWidthInBytes
  1387. @@:
  1388. mov ax,[esi]
  1389. inc esi
  1390. ror ax,cl
  1391. mov [edi],ah
  1392. inc edi
  1393. dec edx
  1394. jnz @B
  1395. add esi,ulTmpSrcDelta
  1396. add edi,ulTmpDstDelta
  1397. dec ebx
  1398. jnz mfNwrnl_scan_loop
  1399. jmp pGlyphLoop
  1400. ;-----------------------------------------------------------------------;
  1401. ; OR first byte, N bytes wide dest, rotated, don't need final source byte.
  1402. ;-----------------------------------------------------------------------;
  1403. or_first_N_wide_rotated_no_last::
  1404. mov eax,ulWidthInBytes
  1405. dec eax ;one less because we don't advance after the
  1406. ; last byte
  1407. mov edx,ulBufDelta
  1408. sub edx,eax
  1409. mov ulTmpDstDelta,edx
  1410. dec eax ;source doesn't advance after first byte, and
  1411. ; we do the first & last bytes outside the
  1412. ; loop; already subtracted 1 above
  1413. mov edx,ulGlyDelta
  1414. sub edx,eax
  1415. mov ulTmpSrcDelta,edx
  1416. mov ulTmpWidthInBytes,eax
  1417. ofNwr_scan_loop:
  1418. mov al,[esi] ;do the initial, ORed byte separately
  1419. shr al,cl
  1420. or [edi],al
  1421. inc edi
  1422. mov edx,ulTmpWidthInBytes
  1423. @@:
  1424. mov ax,[esi]
  1425. inc esi
  1426. ror ax,cl
  1427. mov [edi],ah
  1428. inc edi
  1429. dec edx
  1430. jnz @B
  1431. mov ah,[esi] ;do the final byte separately
  1432. sub al,al
  1433. shr eax,cl
  1434. mov [edi],al
  1435. add esi,ulTmpSrcDelta
  1436. add edi,ulTmpDstDelta
  1437. dec ebx
  1438. jnz ofNwr_scan_loop
  1439. jmp pGlyphLoop
  1440. ;-----------------------------------------------------------------------;
  1441. ; OR all bytes, N bytes wide dest, rotated, don't need final source byte.
  1442. ;-----------------------------------------------------------------------;
  1443. or_all_N_wide_rotated_no_last::
  1444. mov eax,ulWidthInBytes
  1445. dec eax ;one less because we don't advance after the
  1446. ; last byte
  1447. mov edx,ulBufDelta
  1448. sub edx,eax
  1449. mov ulTmpDstDelta,edx
  1450. dec eax ;source doesn't advance after first byte, and
  1451. ; we do the first & last bytes outside the
  1452. ; loop; already subtracted 1 above
  1453. mov edx,ulGlyDelta
  1454. sub edx,eax
  1455. mov ulTmpSrcDelta,edx
  1456. mov ulTmpWidthInBytes,eax
  1457. oaNwr_scan_loop:
  1458. mov al,[esi] ;do the initial, ORed byte separately
  1459. shr al,cl
  1460. or [edi],al
  1461. inc edi
  1462. mov edx,ulTmpWidthInBytes
  1463. @@:
  1464. mov ax,[esi]
  1465. inc esi
  1466. ror ax,cl
  1467. or [edi],ah
  1468. inc edi
  1469. dec edx
  1470. jnz @B
  1471. mov ah,[esi] ;do the final byte separately
  1472. sub al,al
  1473. shr eax,cl
  1474. or [edi],al
  1475. add esi,ulTmpSrcDelta
  1476. add edi,ulTmpDstDelta
  1477. dec ebx
  1478. jnz oaNwr_scan_loop
  1479. jmp pGlyphLoop
  1480. ;-----------------------------------------------------------------------;
  1481. ; MOV first byte, N bytes wide dest, rotated, don't need final source byte.
  1482. ;-----------------------------------------------------------------------;
  1483. mov_first_N_wide_rotated_no_last::
  1484. mov eax,ulWidthInBytes
  1485. dec eax ;one less because we don't advance after the
  1486. ; last byte
  1487. mov edx,ulBufDelta
  1488. sub edx,eax
  1489. mov ulTmpDstDelta,edx
  1490. dec eax ;source doesn't advance after first byte, and
  1491. ; we do the first & last bytes outside the
  1492. ; loop; already subtracted 1 above
  1493. mov edx,ulGlyDelta
  1494. sub edx,eax
  1495. mov ulTmpSrcDelta,edx
  1496. mov ulTmpWidthInBytes,eax
  1497. mfNwr_scan_loop:
  1498. mov al,[esi] ;do the initial byte separately
  1499. shr al,cl
  1500. mov [edi],al
  1501. inc edi
  1502. mov edx,ulTmpWidthInBytes
  1503. @@:
  1504. mov ax,[esi]
  1505. inc esi
  1506. ror ax,cl
  1507. mov [edi],ah
  1508. inc edi
  1509. dec edx
  1510. jnz @B
  1511. mov ah,[esi] ;do the final byte separately
  1512. sub al,al
  1513. shr eax,cl
  1514. mov [edi],al
  1515. add esi,ulTmpSrcDelta
  1516. add edi,ulTmpDstDelta
  1517. dec ebx
  1518. jnz mfNwr_scan_loop
  1519. jmp pGlyphLoop
  1520. ;-----------------------------------------------------------------------;
  1521. ; MOV first byte, N bytes wide dest, unrotated.
  1522. ;-----------------------------------------------------------------------;
  1523. mov_first_N_wide_unrotated::
  1524. mov edx,ulBufDelta
  1525. mov eax,ulWidthInBytes
  1526. sub edx,eax
  1527. shr eax,1 ;width in words
  1528. jc short odd_width ;there's at least one odd byte
  1529. shr eax,1 ;width in dwords
  1530. jc short two_odd_bytes ;there's an odd word
  1531. ;copy width is a dword multiple
  1532. @@:
  1533. mov ecx,eax
  1534. rep movsd ;copy as many dwords as possible
  1535. add edi,edx
  1536. dec ebx
  1537. jnz @B
  1538. jmp pGlyphLoop
  1539. odd_width::
  1540. shr eax,1 ;width in dwords
  1541. jc short three_odd_bytes ;there's an odd word and an odd byte
  1542. ;there's just an odd byte
  1543. inc edx ;because we won't advance after last byte
  1544. @@:
  1545. mov ecx,eax
  1546. rep movsd ;copy as many dwords as possible
  1547. mov cl,[esi]
  1548. inc esi
  1549. mov [edi],cl
  1550. add edi,edx
  1551. dec ebx
  1552. jnz @B
  1553. jmp pGlyphLoop
  1554. two_odd_bytes::
  1555. add edx,2 ;because we won't advance after last word
  1556. @@:
  1557. mov ecx,eax
  1558. rep movsd ;copy as many dwords as possible
  1559. mov cx,[esi]
  1560. add esi,2
  1561. mov [edi],cx
  1562. add edi,edx
  1563. dec ebx
  1564. jnz @B
  1565. jmp pGlyphLoop
  1566. three_odd_bytes::
  1567. add edx,3 ;because we won't advance after last word/byte
  1568. @@:
  1569. mov ecx,eax
  1570. rep movsd ;copy as many dwords as possible
  1571. mov cx,[esi]
  1572. mov [edi],cx
  1573. mov cl,[esi+2]
  1574. add esi,3
  1575. mov [edi+2],cl
  1576. add edi,edx
  1577. dec ebx
  1578. jnz @B
  1579. jmp pGlyphLoop
  1580. ;-----------------------------------------------------------------------;
  1581. ; OR all bytes, N bytes wide dest, unrotated.
  1582. ;-----------------------------------------------------------------------;
  1583. or_all_N_wide_unrotated::
  1584. mov edx,ulBufDelta
  1585. mov eax,ulWidthInBytes
  1586. sub edx,eax
  1587. shr eax,1 ;width in words
  1588. jc short or_odd_width ;there's at least one odd byte
  1589. shr eax,1 ;width in dwords
  1590. jc short or_two_odd_bytes ;there's an odd word
  1591. ;copy width is a dword multiple
  1592. or_no_odd_bytes_loop::
  1593. push ebx ;preserve scan count
  1594. mov ebx,eax
  1595. @@:
  1596. mov ecx,[esi]
  1597. add esi,4
  1598. or [edi],ecx
  1599. add edi,4 ;copy as many dwords as possible
  1600. dec ebx
  1601. jnz @B
  1602. add edi,edx
  1603. pop ebx ;restore scan count
  1604. dec ebx
  1605. jnz or_no_odd_bytes_loop
  1606. jmp pGlyphLoop
  1607. or_odd_width::
  1608. shr eax,1 ;width in dwords
  1609. jc short or_three_odd_bytes ;there's an odd word and an odd byte
  1610. ;there's just an odd byte
  1611. inc edx ;skip over last byte too
  1612. or_one_odd_bytes_loop::
  1613. push ebx ;preserve scan count
  1614. mov ebx,eax
  1615. @@:
  1616. mov ecx,[esi]
  1617. add esi,4
  1618. or [edi],ecx
  1619. add edi,4 ;copy as many dwords as possible
  1620. dec ebx
  1621. jnz @B
  1622. mov cl,[esi]
  1623. or [edi],cl
  1624. inc esi
  1625. add edi,edx
  1626. pop ebx ;restore scan count
  1627. dec ebx
  1628. jnz or_one_odd_bytes_loop
  1629. jmp pGlyphLoop
  1630. or_two_odd_bytes::
  1631. add edx,2 ;skip over last 2 bytes too
  1632. or_two_odd_bytes_loop::
  1633. push ebx ;preserve scan count
  1634. mov ebx,eax
  1635. @@:
  1636. mov ecx,[esi]
  1637. add esi,4
  1638. or [edi],ecx
  1639. add edi,4 ;copy as many dwords as possible
  1640. dec ebx
  1641. jnz @B
  1642. mov cx,[esi]
  1643. or [edi],cx
  1644. add esi,2
  1645. add edi,edx
  1646. pop ebx ;restore scan count
  1647. dec ebx
  1648. jnz or_two_odd_bytes_loop
  1649. jmp pGlyphLoop
  1650. or_three_odd_bytes::
  1651. add edx,3 ;skip over last 3 bytes too
  1652. or_three_odd_bytes_loop::
  1653. push ebx ;preserve scan count
  1654. mov ebx,eax
  1655. @@:
  1656. mov ecx,[esi]
  1657. add esi,4
  1658. or [edi],ecx
  1659. add edi,4 ;copy as many dwords as possible
  1660. dec ebx
  1661. jnz @B
  1662. mov cx,[esi]
  1663. or [edi],cx
  1664. mov cl,[esi+2]
  1665. or [edi+2],cl
  1666. add esi,3
  1667. add edi,edx
  1668. pop ebx ;restore scan count
  1669. dec ebx
  1670. jnz or_three_odd_bytes_loop
  1671. jmp pGlyphLoop
  1672. ;-----------------------------------------------------------------------;
  1673. ; At this point, the text is drawn to the temp buffer.
  1674. ; Now, draw the extra rectangles to the temp buffer.
  1675. ;
  1676. ; Input:
  1677. ; pdsurf = pointer to target surface (screen)
  1678. ; prclText = pointer to text bounding rectangle
  1679. ; prclOpaque = pointer to opaquing rectangle, if there is one
  1680. ; iFgColor = text color
  1681. ; iBgColor = opaquing rectangle color, if there is one
  1682. ; ulTempLeft = X coordinate on dest of left edge of temp buffer pointed
  1683. ; to by pTempBuffer
  1684. ; pTempBuffer = pointer to first byte (upper left corner) of
  1685. ; temp buffer into which we're drawing. This should be
  1686. ; dword-aligned with the destination
  1687. ; ulBufDelta = destination scan-to-scan offset
  1688. ; Text drawn to temp buffer
  1689. ;
  1690. ;-----------------------------------------------------------------------;
  1691. glyphs_are_done::
  1692. extra_rects_are_done::
  1693. exit_fast_text::
  1694. cRet vFastText
  1695. endProc vFastText
  1696. public draw_f_tb_no_to_temp_start
  1697. public draw_nf_tb_no_to_temp_start
  1698. public draw_to_temp_start_entry
  1699. public draw_f_ntb_o_to_temp_start
  1700. public draw_nf_ntb_o_to_temp_start
  1701. public draw_to_temp_start_entry2
  1702. public draw_f_tb_no_to_temp_loop
  1703. public draw_nf_tb_no_to_temp_loop
  1704. public draw_to_temp_loop_entry
  1705. public draw_f_ntb_o_to_temp_loop
  1706. public draw_nf_ntb_o_to_temp_loop
  1707. public draw_to_temp_loop_entry2
  1708. public or_all_1_wide_rotated_need_last
  1709. public or_all_1_wide_rotated_no_last
  1710. public or_first_1_wide_rotated_need_last
  1711. public or_first_1_wide_rotated_no_last
  1712. public or_first_1_wide_rotated_loop
  1713. public mov_first_1_wide_rotated_need_last
  1714. public mov_first_1_wide_rotated_no_last
  1715. public mov_first_1_wide_rotated_loop
  1716. public mov_first_1_wide_unrotated
  1717. public mov_first_1_wide_unrotated_loop
  1718. public or_all_1_wide_unrotated
  1719. public or_all_1_wide_unrotated_loop
  1720. public or_first_2_wide_rotated_need_last
  1721. public or_first_2_wide_rotated_need_loop
  1722. public or_all_2_wide_rotated_need_last
  1723. public or_all_2_wide_rotated_need_loop
  1724. public mov_first_2_wide_rotated_need_last
  1725. public mov_first_2_wide_rotated_need_loop
  1726. public or_first_2_wide_rotated_no_last
  1727. public or_first_2_wide_rotated_loop
  1728. public or_all_2_wide_rotated_no_last
  1729. public or_all_2_wide_rotated_loop
  1730. public mov_first_2_wide_rotated_no_last
  1731. public mov_first_2_wide_rotated_loop
  1732. public mov_first_2_wide_unrotated
  1733. public mov_first_2_wide_unrotated_loop
  1734. public or_all_2_wide_unrotated
  1735. public or_all_2_wide_unrotated_loop
  1736. public or_first_3_wide_rotated_need_last
  1737. public or_all_3_wide_rotated_need_last
  1738. public mov_first_3_wide_rotated_need_last
  1739. public or_first_3_wide_rotated_no_last
  1740. public or_all_3_wide_rotated_no_last
  1741. public mov_first_3_wide_rotated_no_last
  1742. public mov_first_3_wide_unrotated
  1743. public or_all_3_wide_unrotated
  1744. public or_first_4_wide_rotated_need_last
  1745. public or_all_4_wide_rotated_need_last
  1746. public mov_first_4_wide_rotated_need_last
  1747. public or_first_4_wide_rotated_no_last
  1748. public or_all_4_wide_rotated_no_last
  1749. public mov_first_4_wide_rotated_no_last
  1750. public mov_first_4_wide_unrotated
  1751. public or_all_4_wide_unrotated
  1752. public or_first_N_wide_rotated_need_last
  1753. public or_all_N_wide_rotated_need_last
  1754. public mov_first_N_wide_rotated_need_last
  1755. public or_first_N_wide_rotated_no_last
  1756. public or_all_N_wide_rotated_no_last
  1757. public mov_first_N_wide_rotated_no_last
  1758. public mov_first_N_wide_unrotated
  1759. public odd_width
  1760. public two_odd_bytes
  1761. public three_odd_bytes
  1762. public or_all_N_wide_unrotated
  1763. public or_no_odd_bytes_loop
  1764. public or_odd_width
  1765. public or_one_odd_bytes_loop
  1766. public or_two_odd_bytes
  1767. public or_two_odd_bytes_loop
  1768. public or_three_odd_bytes
  1769. public or_three_odd_bytes_loop
  1770. public glyphs_are_done
  1771. public exit_fast_text
  1772. _TEXT$01 ends
  1773. end