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.

1816 lines
74 KiB

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