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.

686 lines
27 KiB

  1. page ,132
  2. ;*****************************Module*Header*******************************\
  3. ; Module Name: cache.asm
  4. ;
  5. ;
  6. ; Created: 9-Dec-1992
  7. ; Author: Paul Butzi
  8. ;
  9. ; Copyright (c) 1990-1999 Microsoft Corporation
  10. ;
  11. ;*************************************************************************/
  12. ; Note: This module would be more efficient with Frame Pointer Omission
  13. ; (FPO), whereby the stack is addressed off ESP rather than EBP, so we
  14. ; could stop pushing and popping EBP. However, the ASM macros currently
  15. ; don't support FPO.
  16. ;*************************************************************************/
  17. .386
  18. .model small,c
  19. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  20. assume fs:nothing,gs:nothing
  21. .xlist
  22. include callconv.inc
  23. include gdii386.inc
  24. .list
  25. .code
  26. EXTRNP xprunFindRunRFONTOBJ,2
  27. EXTRNP xpgdDefault,1
  28. EXTRNP xInsertMetricsRFONTOBJ,3
  29. EXTRNP xInsertMetricsPlusRFONTOBJ,3
  30. EXTRNP xInsertGlyphbitsRFONTOBJ,3
  31. ifdef FE_SB
  32. EXTRNP xwpgdGetLinkMetricsRFONTOBJ,2
  33. EXTRNP xwpgdGetLinkMetricsPlusRFONTOBJ,3
  34. endif
  35. FAST_WCHAR_BASE equ 20h ; Most ANSI fonts have a base of 32
  36. ;******************************Public*Routine******************************\
  37. ;
  38. ; BOOL RFONTOBJ::bGetGlyphMetrics (
  39. ; COUNT c,
  40. ; GLYPHPOS *pgp,
  41. ; WCHAR *pwc
  42. ; );
  43. ;
  44. ; Translate wchars into an array of GLYPHPOS structures, filling in
  45. ; the pointer to GLYPHDATA field. Only the metrics are assured to be
  46. ; valid; no attempt is made to ensure that the glyph data itself is
  47. ; present in the cache before the return to the caller.
  48. ;
  49. ; This routine is to be used primarily by GetTextExtent and GetCharWidths,
  50. ; which have no need for anything except metrics.
  51. ;
  52. ; A zero return means that we failed to insert the metrics due to some
  53. ; hard error, most likely a failure to commit memory in the glyph
  54. ; insertion routine.
  55. ;
  56. ; History:
  57. ; 21-Dec-92 -by- Michael Abrash
  58. ; Fixed bug in detecting run inclusion
  59. ; 9-Dec-92 -by- Paul Butzi
  60. ; Wrote it.
  61. ;**************************************************************************/
  62. cPublicProc xGetGlyphMetrics,4,< \
  63. uses ebx esi edi, \
  64. pThis: ptr dword, \
  65. c_: dword, \
  66. pgp: ptr dword, \
  67. pwc: dword >
  68. mov eax, pThis ; (eax) = ptr to RFONTOBJ
  69. mov eax, [eax].prfnt ; (eax) = ptr to RFONT
  70. mov esi, pwc ; pointer to wchar data
  71. ;*486 pipelining
  72. mov eax, [eax].wcgp ; (eax) = ptr to wcgp
  73. mov edi, pgp ; pointer to glyphpos array to fill
  74. ;*486 pipelining
  75. lea ebx, [eax].agprun ; (ebx) = ptr to first wcgp run
  76. ;*486 pipelining
  77. mov ecx, [ebx].wcLow ; index of start of run
  78. mov edx, [ebx].cGlyphs ; # of glyphs in run
  79. mov ebx, [ebx].apgd ; pointer to run's pointers to cached
  80. ; glyphdata
  81. push ebp
  82. mov ebp,c_ ; we'll use EBP for the glyph count
  83. ; ***stack frame no longer available***
  84. ;
  85. ; Invariants:
  86. ; (esi) = ptr to wchar
  87. ; (edi) = ptr to pgp
  88. ; (ebx) = ptr to base of current run
  89. ; (ecx) = wcLow of current run
  90. ; (edx) = cGlyphs of current run
  91. ; (ebp) = count of glyphs remaining
  92. loop_top:
  93. sub eax, eax
  94. mov ax, [esi] ; (eax) = wchar, zero extended
  95. sub eax, ecx ; get index relative to current run base
  96. cmp eax, edx ; is wchar in this run?
  97. jae short find_run ; wrong run, better go get right one
  98. run_found:
  99. mov eax, [ebx+4*eax] ; (ecx) = ptr to glyphdata
  100. ;
  101. ; Invariants:
  102. ; (esi, edi, ebx, ecx, edx) as above at loop top
  103. ; (eax) = ptr to glyphdata
  104. ;
  105. default_found:
  106. and eax, eax ; is cached glyphdata there?
  107. jz short get_glyph ; no glyphdata, better go get one
  108. ;
  109. ; Here, we are assured that the glyphdata is present in the cache
  110. ;
  111. glyph_found:
  112. mov [edi].gp_pgdf, eax ; set ptr to glyphdata in glyphpos
  113. mov eax, [eax].gd_hg
  114. mov [edi].gp_hg, eax ; set hg in glyphpos
  115. add edi, SIZE_GLYPHPOS ; next glyphpos to fill in
  116. add esi, 2 ; next wchar to look up
  117. dec ebp ; any more glyphs?
  118. jnz loop_top
  119. pop ebp ; ***stack frame available***
  120. mov eax, 1 ; success
  121. stdRET xGetGlyphMetrics
  122. ;=======================================================================
  123. ; We got here because the current run does not contain the wchar we're
  124. ; interested in. Note that the following invariants must hold when
  125. ; we re-enter the loop (starred items must hold on entry, as well):
  126. ; (esi) = ptr to wchar*
  127. ; (edi) = ptr to pgp*
  128. ; (ebx) = ptr to apgd of new run
  129. ; (ecx) = wcLow of new run
  130. ; (edx) = cGlyphs of new run
  131. ; (eax) = ptr to glyphdata
  132. ; (ebp) = count of glyphs remaining*
  133. ;=======================================================================
  134. align 4
  135. find_run:
  136. push ebp ; preserve count of remaining glpyhs
  137. mov ebp,[esp+4] ; ***stack frame available***
  138. ; *****************************************
  139. ; * Note that the approach here is to get *
  140. ; * EBP off the stack, where it was *
  141. ; * pushed, by addressing off ESP. EBP *
  142. ; * remains pushed, so we don't need to *
  143. ; * re-push it when we're done. *
  144. ; * XCHGing EBP with the top of the stack *
  145. ; * would be cleaner, but XCHG locks the *
  146. ; * bus. *
  147. ; * This trick is repeated several times *
  148. ; * below. *
  149. ; *****************************************
  150. sub eax, eax
  151. mov ax, [esi] ; (eax) = current wchar
  152. mov ebx, pThis
  153. stdcall xprunFindRunRFONTOBJ, <ebx, eax> ; find the wchar's run
  154. pop ebp ; <ebp> = glyph count
  155. ; ***stack frame no longer available***
  156. mov ecx, [eax].wcLow ; index of start of new run
  157. mov edx, [eax].cGlyphs ; # of glyphs in new run
  158. mov ebx, [eax].apgd ; pointer to new run's pointers to
  159. ; cached glyphdata
  160. sub eax, eax
  161. mov ax, [esi] ; (eax) = current wchar
  162. sub eax, ecx ; get index relative to new run base
  163. cmp eax, edx ; is wchar in this run?
  164. jb run_found ; yes, run with it
  165. ; not in any run; use default character
  166. push ebp ; preserve count of remaining glyphs
  167. mov ebp,[esp+4] ; ***stack frame available***
  168. ifdef FE_SB ; call off to linked font handler
  169. push ebx
  170. push ecx
  171. push edx
  172. mov eax, pThis ; (eax) = pointer to RFONTOBJ
  173. sub ebx,ebx ; (ebx) = 0
  174. mov bx, [esi] ; (ebx) = current wchar
  175. stdcall xwpgdGetLinkMetricsRFONTOBJ,<eax,ebx>
  176. pop edx
  177. pop ecx
  178. pop ebx
  179. else
  180. mov eax, pThis
  181. push ecx
  182. push edx
  183. stdcall xpgdDefault, <eax> ; eax = ptr to default character
  184. pop edx
  185. pop ecx
  186. endif
  187. pop ebp ; <ebp> = glyph count
  188. jmp default_found ; go with the default character
  189. ;=======================================================================
  190. ; We got here because the glyph pointer in the wcgp run was null, meaning
  191. ; we don't yet have the metrics for this glyph. Note that the following
  192. ; invariants must be true on exit (starred items must hold on entry, as
  193. ; well):
  194. ; (esi) = ptr to wchar*
  195. ; (edi) = ptr to pgp*
  196. ; (ebx) = ptr to apgd of new run*
  197. ; (ecx) = wcLow of new run*
  198. ; (edx) = cGlyphs of new run*
  199. ; (eax) = ptr to glyphdata
  200. ; (ebp) = count of glyphs remaining*
  201. ;=======================================================================
  202. align 4
  203. get_glyph:
  204. push ebp ; preserve count of remaining glpyhs
  205. mov ebp,[esp+4] ; ***stack frame available***
  206. push ebx
  207. push edx
  208. push ecx
  209. sub eax, eax
  210. mov ax, [esi] ; (eax) = wchar
  211. mov edx, eax ; set aside wchar
  212. sub eax, ecx ; (eax) = index into run
  213. lea ebx, [ebx+eax*4] ; (ebx) = ptr to entry
  214. mov ecx,pThis
  215. stdcall xInsertMetricsRFONTOBJ, <ecx, ebx, edx>
  216. pop ecx
  217. pop edx
  218. and eax, eax ; were we able to get the glyph metrics?
  219. jz short failed ; no
  220. mov eax, [ebx] ; get ptr to glyphdata from cache entry
  221. pop ebx
  222. pop ebp ; <ebp> = glyph count
  223. ; ***stack frame no longer available***
  224. jmp glyph_found
  225. failed:
  226. pop ebx
  227. pop eax ; clear glyph count from stack
  228. pop eax ; clear pushed stack frame pointer from stack
  229. sub eax, eax ; failure
  230. stdRET xGetGlyphMetrics
  231. stdENDP xGetGlyphMetrics
  232. ;******************************Public*Routine******************************\
  233. ;
  234. ; BOOL RFONTOBJ::bGetGlyphMetricsPlus (
  235. ; COUNT c,
  236. ; GLYPHPOS *pgp,
  237. ; WCHAR *pwc,
  238. ; BOOL *pbAccel
  239. ; );
  240. ;
  241. ; Translate wchars into an array of GLYPHPOS structures, filling in
  242. ; the pointer to GLYPHDATA field. Although only the metrics are assured to be
  243. ; valid, an attempt is made to ensure that the glyph data itself is
  244. ; present in the cache before the return to the caller. Failure in this
  245. ; attempt is indicated by clearing the flag *pbAccel. This allows the
  246. ; text code to tell the device driver that the STROBJ_bEnum callback is
  247. ; not needed.
  248. ;
  249. ; This routine is to be used primarily by TextOut and its kin.
  250. ;
  251. ; A zero return means that we failed to insert the metrics due to some
  252. ; hard error, most likely a failure to commit memory in the glyph
  253. ; insertion routine.
  254. ;
  255. ; This is a replacement for the C++ version in cache.cxx
  256. ;
  257. ; History:
  258. ; 21-Dec-92 -by- Michael Abrash
  259. ; Fixed bug in detecting run inclusion
  260. ; 9-Dec-92 -by- Paul Butzi
  261. ; Wrote it.
  262. ;**************************************************************************/
  263. cPublicProc xGetGlyphMetricsPlus,5,< \
  264. uses ebx esi edi, \
  265. pThis: ptr dword, \
  266. c_: dword, \
  267. pgp: ptr dword, \
  268. pwc: dword, \
  269. pbAccel: ptr dword >
  270. local pbacceltmp : dword ;1 if all glyph bits have been gotten
  271. ; so far, 0 if not
  272. mov eax, pThis ; (eax) = ptr to RFONTOBJ
  273. mov pbacceltmp,1 ; set bAccel to true (all glyph bits
  274. ; realized so far)
  275. ;*486 pipelining
  276. mov eax, [eax].prfnt ; (eax) = ptr to RFONT
  277. mov esi, pwc ; pointer to wchar data
  278. ;*486 pipelining
  279. mov eax, [eax].wcgp ; (eax) = ptr to wcgp
  280. mov edi, pgp ; pointer to glyphpos array to fill
  281. ;*486 pipelining
  282. lea ebx, [eax].agprun ; (ebx) = ptr to first wcgp run
  283. ;*486 pipelining
  284. push ebp ;*486 pipelining
  285. mov ecx, [ebx].wcLow ; index of start of run
  286. mov edx, [ebx].cGlyphs ; # of glyphs in run
  287. mov ebx, [ebx].apgd ; pointer to run's pointers to cached
  288. ; glyphdata
  289. mov ebp,c_ ; we'll use EBP for the glyph count
  290. ; ***stack frame no longer available***
  291. ;--------------------------------------------------------------------------
  292. ; Fast two-glyphs-at-a-time Pentium pipe-lined loop
  293. ;
  294. ; The philosophy of this loop is that for the vast majority of the time,
  295. ; all the glyphs will be in the proper range, have cached glyphdata, and
  296. ; have cached glyphbits -- and it takes advantage of that to better make
  297. ; use of both Pentium pipes by doing two glyphs at once. If one of those
  298. ; conditions fail, it converts to the single-glyph-at-a-time loop when
  299. ; that happens.
  300. ;
  301. ; Invariants:
  302. ; (esi) = ptr to 1st wchar
  303. ; (edi) = ptr to pgp
  304. ; (ecx) = ptr to 2nd wchar
  305. ; (ecx) = wcLow of current run
  306. ; (edx) = cGlyphs of current run
  307. ; (ebp) = count of glyphs remaining
  308. ; [esp] = wcLow of current run
  309. cmp ecx, FAST_WCHAR_BASE ; fast loop handles wcLow values only
  310. jne gmp_slow_loop_top ; of 32
  311. dec ebp ; pre-decrement count
  312. jz gmp_slow_loop_top ; only one character. it's okay to
  313. ; pop this through to gmp_slow_loop_top
  314. ; with a zero count -- it's effectively
  315. ; the same as a one count
  316. push ecx ; wcLow is now at [esp]
  317. gmp_fast_loop_top:
  318. mov eax, [esi] ; 1U (eax) = first two glyphs
  319. add edi, 2*SIZE_GLYPHPOS ; 1V each iteration does two glyphpos's.
  320. ; we do this now to eat up a free V
  321. ; pipe instruction
  322. mov ecx, eax ; 1U
  323. add esi, 4 ; 1V each iteration does two wchars.
  324. ; we do this now to eat up a free V
  325. ; pipe instruction
  326. shr ecx, 16 ; 1U (ecx) = 2nd wchar, zero extended
  327. and eax, 0ffffh ; 1V (eax) = 1st wchar, zero extended
  328. sub eax, FAST_WCHAR_BASE ; 1U get index relative to current base
  329. sub ecx, FAST_WCHAR_BASE ; 1V get index relative to current base
  330. cmp eax, edx ; 1U is 1st wchar in this run?
  331. jae gmp_restart_in_slow_loop; 1V wrong run, exit fast loop
  332. cmp ecx, edx ; 1U is 2nd wchar in this run?
  333. jae gmp_restart_in_slow_loop; 1V wrong run, exit fast loop
  334. mov eax, [ebx+4*eax] ; 2U (eax) = ptr to 1st glyphdata
  335. mov ecx, [ebx+4*ecx] ; 2V (ecx) = ptr to 2nd glyphdata
  336. ; (could be 3V if in same cache
  337. ; bank)
  338. test eax, eax ; 1U is 1st cached glyphdata there?
  339. jz gmp_restart_in_slow_loop; 1V no glyphdata, exit fast loop
  340. test ecx, ecx ; 1U is 2nd cached glyphdata there?
  341. jz gmp_restart_in_slow_loop; 1V no glyphdata, exit fast loop
  342. cmp dword ptr [eax].gd_gdf, 0 ; 2U are 1st glyph bits in cache?
  343. je gmp_restart_in_slow_loop ; 1V no, go get them
  344. cmp dword ptr [ecx].gd_gdf, 0 ; 2U are 2nd glyph bits in cache?
  345. je gmp_restart_in_slow_loop ; 1V no, go get them
  346. mov [edi-2*SIZE_GLYPHPOS].gp_pgdf, eax
  347. ; 1U set ptr to glyphdata in glyphpos
  348. mov eax, [eax].gd_hg ; 1V read 1st glyph handle
  349. mov [edi-1*SIZE_GLYPHPOS].gp_pgdf, ecx
  350. ; 1U set ptr to glyphdata in glyphpos
  351. mov ecx, [ecx].gd_hg ; 1V read 2nd glyph handle
  352. mov [edi-2*SIZE_GLYPHPOS].gp_hg,eax ; 1U set handle in glyphpos
  353. mov [edi-1*SIZE_GLYPHPOS].gp_hg,ecx ; 1V set handle in glyphpos
  354. sub ebp, 2 ; 1U each iteration does two glyphs
  355. jg gmp_fast_loop_top ; 1V more loops to do
  356. pop ecx ; account for pushed wcLow
  357. jz gmp_slow_loop_top ; odd number of glyphs, handle last one
  358. pop ebp ; ***stack frame available***
  359. mov ebx,pbaccel ; where we'll store whether all glyph
  360. ; bits found
  361. mov eax, 1 ; success
  362. mov [ebx], 1 ; success
  363. stdRET xGetGlyphMetricsPlus
  364. ;--------------------------------------------------------------------------
  365. ; Not-so-fast one-glyph-at-a-time loop
  366. ;
  367. ; Invariants:
  368. ; (esi) = ptr to wchar
  369. ; (edi) = ptr to pgp
  370. ; (ebx) = ptr to base of current run
  371. ; (ecx) = wcLow of current run
  372. ; (edx) = cGlyphs of current run
  373. ; (ebp) = count of glyphs remaining
  374. gmp_restart_in_slow_loop:
  375. pop ecx ; (ecx) = wcLow of current run
  376. inc ebp ; account for fast-loop preadjustments
  377. sub edi, 2*SIZE_GLYPHPOS
  378. sub esi, 4
  379. gmp_slow_loop_top:
  380. sub eax, eax
  381. mov ax, [esi] ; (eax) = wchar, zero extended
  382. sub eax, ecx ; get index relative to current run base
  383. cmp eax, edx ; is wchar in this run?
  384. jae short gmp_find_run ; wrong run, better go get right one
  385. gmp_run_found:
  386. mov eax, [ebx+4*eax] ; (ecx) = ptr to glyphdata
  387. ;
  388. ; Invariants:
  389. ; (esi, edi, ebx, ecx, edx) as above at loop top
  390. ; (eax) = ptr to glyphdata
  391. ;
  392. gmp_default_found:
  393. and eax, eax ; is cached glyphdata there?
  394. jz gmp_get_glyph ; no glyphdata, better go get one
  395. ;
  396. ; Here, we are assured that the glyphdata is present in the cache
  397. ;
  398. gmp_glyph_found:
  399. cmp dword ptr [eax].gd_gdf, 0 ; are the glyph bits in the cache?
  400. jz gmp_get_bits ; no, go get them
  401. ;
  402. ; Here, we have tried to get the glyphbits in the cache
  403. ;
  404. gmp_got_bits:
  405. mov [edi].gp_pgdf, eax ; set ptr to glyphdata in glyphpos
  406. mov eax, [eax].gd_hg
  407. mov [edi].gp_hg, eax ; set hg in glyphpos
  408. add edi, SIZE_GLYPHPOS ; next glyphpos to fill in
  409. add esi, 2 ; next wchar to look up
  410. dec ebp ; any more glyphs?
  411. jg gmp_slow_loop_top ; must be 'greater than' check
  412. pop ebp ; ***stack frame available***
  413. mov ebx,pbaccel ; where we'll store whether all glyph bits found
  414. mov eax,pbacceltmp ; 0 if not all found, 1 if all found
  415. mov [ebx],eax ; return whether we found all glyph bits or not
  416. mov eax, 1 ; success
  417. stdRET xGetGlyphMetricsPlus
  418. ;=======================================================================
  419. ; We got here because the current run does not contain the wchar we're
  420. ; interested in. Note that the following invariants must hold when
  421. ; we re-enter the loop (starred items must hold on entry, as well):
  422. ; (esi) = ptr to wchar*
  423. ; (edi) = ptr to pgp*
  424. ; (ebx) = ptr to apgd of new run
  425. ; (ecx) = wcLow of new run
  426. ; (edx) = cGlyphs of new run
  427. ; (eax) = ptr to glyphdata
  428. ; (ebp) = count of glyphs remaining*
  429. ;=======================================================================
  430. align 4
  431. gmp_find_run:
  432. push ebp ; preserve count of remaining glpyhs
  433. mov ebp,[esp+4] ; ***stack frame available***
  434. sub eax, eax
  435. mov ax, [esi] ; (eax) = current wchar
  436. mov ebx, pThis
  437. stdcall xprunFindRunRFONTOBJ, <ebx, eax>
  438. pop ebp ; <ebp> = glyph count
  439. ; ***stack frame no longer available***
  440. mov ecx, [eax].wcLow ; index of start of new run
  441. mov edx, [eax].cGlyphs ; # of glyphs in new run
  442. mov ebx, [eax].apgd ; pointer to new run's pointers to
  443. ; cached glyphdata
  444. sub eax, eax
  445. mov ax, [esi] ; (eax) = current wchar
  446. sub eax, ecx ; get index relative to new run base
  447. cmp eax, edx ; is wchar in this run?
  448. jb gmp_run_found ; yes, run with it
  449. ; not in any run; use default character
  450. push ebp ; preserve count of remaining glyphs
  451. mov ebp,[esp+4] ; ***stack frame available***
  452. ifdef FE_SB
  453. push ebx
  454. push ecx
  455. push edx
  456. mov eax, pThis ; (eax) = pointer to RFONTOBJ
  457. lea ebx, pbacceltmp ; (ebx) = pointer to pbacceltmp
  458. ; (esi) = pointer to current wchar
  459. stdcall xwpgdGetLinkMetricsPlusRFONTOBJ,<eax,esi,ebx>
  460. pop edx
  461. pop ecx
  462. pop ebx ; (eax) is now proper wpgd
  463. else
  464. mov eax,pThis
  465. push ecx
  466. push edx
  467. stdcall xpgdDefault, <eax> ; eax = ptr to default character
  468. pop edx
  469. pop ecx
  470. endif
  471. pop ebp ; <ebp> = glyph count
  472. ; ***stack frame no longer available***
  473. jmp gmp_default_found ; go with the default character
  474. ;=======================================================================
  475. ; We got here because the glyph pointer in the wcgp run was null, meaning
  476. ; we don't yet have the metrics for this glyph. Note that the following
  477. ; invariants must be true on exit (starred items must hold on entry, as
  478. ; well):
  479. ; (esi) = ptr to wchar*
  480. ; (edi) = ptr to pgp*
  481. ; (ebx) = ptr to apgd of new run*
  482. ; (ecx) = wcLow of new run*
  483. ; (edx) = cGlyphs of new run*
  484. ; (eax) = ptr to glyphdata
  485. ; (ebp) = count of glyphs remaining*
  486. ;=======================================================================
  487. align 4
  488. gmp_get_glyph:
  489. push ebp ; preserve count of remaining glpyhs
  490. mov ebp,[esp+4] ; ***stack frame available***
  491. push ebx
  492. push edx
  493. push ecx
  494. sub eax, eax
  495. mov ax, [esi] ; (eax) = wchar
  496. mov edx, eax ; set aside wchar
  497. sub eax, ecx ; (eax) = index into run
  498. lea ebx, [ebx+4*eax] ; (ebx) = ptr to entry
  499. mov ecx,pThis
  500. stdcall xInsertMetricsPlusRFONTOBJ, <ecx, ebx, edx>
  501. pop ecx
  502. pop edx
  503. and eax, eax ; were we able to get the glyph metrics?
  504. jz short gmp_failed ; no
  505. mov eax, [ebx] ; get ptr to glyphdata from it
  506. pop ebx
  507. pop ebp ; <ebp> = glyph count
  508. ; ***stack frame no longer available***
  509. jmp gmp_glyph_found
  510. gmp_failed:
  511. pop ebx
  512. pop eax ; clear glyph count from stack
  513. pop eax ; clear pushed stack frame pointer from stack
  514. sub eax, eax ;failure
  515. stdRET xGetGlyphMetricsPlus
  516. ;=======================================================================
  517. ; We get here if we need to try to load the bits for the glyph we're
  518. ; interested in (because the bits havene't been realized yet). We only
  519. ; even bother to try if all bits have successfully been realized so far,
  520. ; because it's only useful to realize glyphs if we can get all of them.
  521. ; Note that the following invariants must be true on both entry and exit.
  522. ; (esi) = ptr to wchar
  523. ; (edi) = ptr to pgp
  524. ; (ebx) = ptr to apgd of new run
  525. ; (ecx) = wcLow of new run
  526. ; (edx) = cGlyphs of new run
  527. ; (eax) = ptr to glyphdata
  528. ; (ebp) = count of glyphs remaining
  529. ;=======================================================================
  530. align 4
  531. gmp_get_bits:
  532. push ebp ; preserve count of remaining glpyhs
  533. mov ebp,[esp+4] ; ***stack frame available***
  534. cmp pbacceltmp,0 ;if we already failed to get glyph bits
  535. je short got_the_bits_done ; once, no point in trying again
  536. push ecx
  537. mov ecx, pThis
  538. push edx ;*486 pipelining
  539. mov edx, [ecx].prfnt
  540. push eax ;*486 pipelining
  541. cmp dword ptr [edx].ulContent, FO_HGLYPHS
  542. je short got_the_bits
  543. sub edx,edx
  544. cmp pwc,esi
  545. sbb edx,-1 ; EDX == TRUE if first wc, FALSE else
  546. stdcall xInsertGlyphbitsRFONTOBJ, <ecx, eax, edx> ;try to get the bits
  547. and eax, eax ; did we succeed in getting the bits?
  548. jnz short got_the_bits ; yes, we got the bits
  549. mov pbacceltmp, eax ; didn't get the glyph (note: EAX is zero)
  550. got_the_bits:
  551. pop eax
  552. pop edx
  553. pop ecx
  554. got_the_bits_done:
  555. pop ebp ; <ebp> = glyph count
  556. ; ***stack frame no longer available***
  557. jmp gmp_got_bits
  558. stdENDP xGetGlyphMetricsPlus
  559. end