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
686 lines
27 KiB
page ,132
|
|
;*****************************Module*Header*******************************\
|
|
; Module Name: cache.asm
|
|
;
|
|
;
|
|
; Created: 9-Dec-1992
|
|
; Author: Paul Butzi
|
|
;
|
|
; Copyright (c) 1990-1999 Microsoft Corporation
|
|
;
|
|
;*************************************************************************/
|
|
; Note: This module would be more efficient with Frame Pointer Omission
|
|
; (FPO), whereby the stack is addressed off ESP rather than EBP, so we
|
|
; could stop pushing and popping EBP. However, the ASM macros currently
|
|
; don't support FPO.
|
|
;*************************************************************************/
|
|
|
|
.386
|
|
.model small,c
|
|
|
|
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
|
|
assume fs:nothing,gs:nothing
|
|
|
|
.xlist
|
|
include callconv.inc
|
|
include gdii386.inc
|
|
.list
|
|
|
|
|
|
.code
|
|
EXTRNP xprunFindRunRFONTOBJ,2
|
|
EXTRNP xpgdDefault,1
|
|
EXTRNP xInsertMetricsRFONTOBJ,3
|
|
EXTRNP xInsertMetricsPlusRFONTOBJ,3
|
|
EXTRNP xInsertGlyphbitsRFONTOBJ,3
|
|
|
|
ifdef FE_SB
|
|
EXTRNP xwpgdGetLinkMetricsRFONTOBJ,2
|
|
EXTRNP xwpgdGetLinkMetricsPlusRFONTOBJ,3
|
|
endif
|
|
|
|
|
|
FAST_WCHAR_BASE equ 20h ; Most ANSI fonts have a base of 32
|
|
|
|
;******************************Public*Routine******************************\
|
|
;
|
|
; BOOL RFONTOBJ::bGetGlyphMetrics (
|
|
; COUNT c,
|
|
; GLYPHPOS *pgp,
|
|
; WCHAR *pwc
|
|
; );
|
|
;
|
|
; Translate wchars into an array of GLYPHPOS structures, filling in
|
|
; the pointer to GLYPHDATA field. Only the metrics are assured to be
|
|
; valid; no attempt is made to ensure that the glyph data itself is
|
|
; present in the cache before the return to the caller.
|
|
;
|
|
; This routine is to be used primarily by GetTextExtent and GetCharWidths,
|
|
; which have no need for anything except metrics.
|
|
;
|
|
; A zero return means that we failed to insert the metrics due to some
|
|
; hard error, most likely a failure to commit memory in the glyph
|
|
; insertion routine.
|
|
;
|
|
; History:
|
|
; 21-Dec-92 -by- Michael Abrash
|
|
; Fixed bug in detecting run inclusion
|
|
; 9-Dec-92 -by- Paul Butzi
|
|
; Wrote it.
|
|
;**************************************************************************/
|
|
|
|
|
|
|
|
cPublicProc xGetGlyphMetrics,4,< \
|
|
uses ebx esi edi, \
|
|
pThis: ptr dword, \
|
|
c_: dword, \
|
|
pgp: ptr dword, \
|
|
pwc: dword >
|
|
mov eax, pThis ; (eax) = ptr to RFONTOBJ
|
|
mov eax, [eax].prfnt ; (eax) = ptr to RFONT
|
|
mov esi, pwc ; pointer to wchar data
|
|
;*486 pipelining
|
|
mov eax, [eax].wcgp ; (eax) = ptr to wcgp
|
|
mov edi, pgp ; pointer to glyphpos array to fill
|
|
;*486 pipelining
|
|
lea ebx, [eax].agprun ; (ebx) = ptr to first wcgp run
|
|
;*486 pipelining
|
|
mov ecx, [ebx].wcLow ; index of start of run
|
|
mov edx, [ebx].cGlyphs ; # of glyphs in run
|
|
mov ebx, [ebx].apgd ; pointer to run's pointers to cached
|
|
; glyphdata
|
|
|
|
push ebp
|
|
mov ebp,c_ ; we'll use EBP for the glyph count
|
|
; ***stack frame no longer available***
|
|
;
|
|
; Invariants:
|
|
; (esi) = ptr to wchar
|
|
; (edi) = ptr to pgp
|
|
; (ebx) = ptr to base of current run
|
|
; (ecx) = wcLow of current run
|
|
; (edx) = cGlyphs of current run
|
|
; (ebp) = count of glyphs remaining
|
|
loop_top:
|
|
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = wchar, zero extended
|
|
|
|
sub eax, ecx ; get index relative to current run base
|
|
cmp eax, edx ; is wchar in this run?
|
|
jae short find_run ; wrong run, better go get right one
|
|
|
|
run_found:
|
|
|
|
mov eax, [ebx+4*eax] ; (ecx) = ptr to glyphdata
|
|
|
|
|
|
;
|
|
; Invariants:
|
|
; (esi, edi, ebx, ecx, edx) as above at loop top
|
|
; (eax) = ptr to glyphdata
|
|
;
|
|
default_found:
|
|
and eax, eax ; is cached glyphdata there?
|
|
jz short get_glyph ; no glyphdata, better go get one
|
|
|
|
;
|
|
; Here, we are assured that the glyphdata is present in the cache
|
|
;
|
|
glyph_found:
|
|
mov [edi].gp_pgdf, eax ; set ptr to glyphdata in glyphpos
|
|
mov eax, [eax].gd_hg
|
|
mov [edi].gp_hg, eax ; set hg in glyphpos
|
|
|
|
|
|
add edi, SIZE_GLYPHPOS ; next glyphpos to fill in
|
|
add esi, 2 ; next wchar to look up
|
|
|
|
dec ebp ; any more glyphs?
|
|
jnz loop_top
|
|
|
|
pop ebp ; ***stack frame available***
|
|
|
|
mov eax, 1 ; success
|
|
stdRET xGetGlyphMetrics
|
|
|
|
|
|
|
|
|
|
;=======================================================================
|
|
; We got here because the current run does not contain the wchar we're
|
|
; interested in. Note that the following invariants must hold when
|
|
; we re-enter the loop (starred items must hold on entry, as well):
|
|
; (esi) = ptr to wchar*
|
|
; (edi) = ptr to pgp*
|
|
; (ebx) = ptr to apgd of new run
|
|
; (ecx) = wcLow of new run
|
|
; (edx) = cGlyphs of new run
|
|
; (eax) = ptr to glyphdata
|
|
; (ebp) = count of glyphs remaining*
|
|
;=======================================================================
|
|
align 4
|
|
find_run:
|
|
push ebp ; preserve count of remaining glpyhs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
; *****************************************
|
|
; * Note that the approach here is to get *
|
|
; * EBP off the stack, where it was *
|
|
; * pushed, by addressing off ESP. EBP *
|
|
; * remains pushed, so we don't need to *
|
|
; * re-push it when we're done. *
|
|
; * XCHGing EBP with the top of the stack *
|
|
; * would be cleaner, but XCHG locks the *
|
|
; * bus. *
|
|
; * This trick is repeated several times *
|
|
; * below. *
|
|
; *****************************************
|
|
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = current wchar
|
|
mov ebx, pThis
|
|
stdcall xprunFindRunRFONTOBJ, <ebx, eax> ; find the wchar's run
|
|
|
|
pop ebp ; <ebp> = glyph count
|
|
; ***stack frame no longer available***
|
|
mov ecx, [eax].wcLow ; index of start of new run
|
|
mov edx, [eax].cGlyphs ; # of glyphs in new run
|
|
mov ebx, [eax].apgd ; pointer to new run's pointers to
|
|
; cached glyphdata
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = current wchar
|
|
sub eax, ecx ; get index relative to new run base
|
|
cmp eax, edx ; is wchar in this run?
|
|
jb run_found ; yes, run with it
|
|
; not in any run; use default character
|
|
push ebp ; preserve count of remaining glyphs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
ifdef FE_SB ; call off to linked font handler
|
|
push ebx
|
|
push ecx
|
|
push edx
|
|
mov eax, pThis ; (eax) = pointer to RFONTOBJ
|
|
sub ebx,ebx ; (ebx) = 0
|
|
mov bx, [esi] ; (ebx) = current wchar
|
|
stdcall xwpgdGetLinkMetricsRFONTOBJ,<eax,ebx>
|
|
pop edx
|
|
pop ecx
|
|
pop ebx
|
|
else
|
|
mov eax, pThis
|
|
push ecx
|
|
push edx
|
|
stdcall xpgdDefault, <eax> ; eax = ptr to default character
|
|
pop edx
|
|
pop ecx
|
|
endif
|
|
pop ebp ; <ebp> = glyph count
|
|
jmp default_found ; go with the default character
|
|
|
|
;=======================================================================
|
|
; We got here because the glyph pointer in the wcgp run was null, meaning
|
|
; we don't yet have the metrics for this glyph. Note that the following
|
|
; invariants must be true on exit (starred items must hold on entry, as
|
|
; well):
|
|
; (esi) = ptr to wchar*
|
|
; (edi) = ptr to pgp*
|
|
; (ebx) = ptr to apgd of new run*
|
|
; (ecx) = wcLow of new run*
|
|
; (edx) = cGlyphs of new run*
|
|
; (eax) = ptr to glyphdata
|
|
; (ebp) = count of glyphs remaining*
|
|
;=======================================================================
|
|
align 4
|
|
get_glyph:
|
|
push ebp ; preserve count of remaining glpyhs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
|
|
push ebx
|
|
push edx
|
|
push ecx
|
|
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = wchar
|
|
mov edx, eax ; set aside wchar
|
|
sub eax, ecx ; (eax) = index into run
|
|
lea ebx, [ebx+eax*4] ; (ebx) = ptr to entry
|
|
mov ecx,pThis
|
|
stdcall xInsertMetricsRFONTOBJ, <ecx, ebx, edx>
|
|
pop ecx
|
|
pop edx
|
|
and eax, eax ; were we able to get the glyph metrics?
|
|
jz short failed ; no
|
|
|
|
mov eax, [ebx] ; get ptr to glyphdata from cache entry
|
|
|
|
pop ebx
|
|
|
|
pop ebp ; <ebp> = glyph count
|
|
; ***stack frame no longer available***
|
|
jmp glyph_found
|
|
|
|
failed:
|
|
pop ebx
|
|
|
|
pop eax ; clear glyph count from stack
|
|
pop eax ; clear pushed stack frame pointer from stack
|
|
|
|
sub eax, eax ; failure
|
|
stdRET xGetGlyphMetrics
|
|
|
|
stdENDP xGetGlyphMetrics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;******************************Public*Routine******************************\
|
|
;
|
|
; BOOL RFONTOBJ::bGetGlyphMetricsPlus (
|
|
; COUNT c,
|
|
; GLYPHPOS *pgp,
|
|
; WCHAR *pwc,
|
|
; BOOL *pbAccel
|
|
; );
|
|
;
|
|
; Translate wchars into an array of GLYPHPOS structures, filling in
|
|
; the pointer to GLYPHDATA field. Although only the metrics are assured to be
|
|
; valid, an attempt is made to ensure that the glyph data itself is
|
|
; present in the cache before the return to the caller. Failure in this
|
|
; attempt is indicated by clearing the flag *pbAccel. This allows the
|
|
; text code to tell the device driver that the STROBJ_bEnum callback is
|
|
; not needed.
|
|
;
|
|
; This routine is to be used primarily by TextOut and its kin.
|
|
;
|
|
; A zero return means that we failed to insert the metrics due to some
|
|
; hard error, most likely a failure to commit memory in the glyph
|
|
; insertion routine.
|
|
;
|
|
; This is a replacement for the C++ version in cache.cxx
|
|
;
|
|
; History:
|
|
; 21-Dec-92 -by- Michael Abrash
|
|
; Fixed bug in detecting run inclusion
|
|
; 9-Dec-92 -by- Paul Butzi
|
|
; Wrote it.
|
|
;**************************************************************************/
|
|
|
|
|
|
cPublicProc xGetGlyphMetricsPlus,5,< \
|
|
uses ebx esi edi, \
|
|
pThis: ptr dword, \
|
|
c_: dword, \
|
|
pgp: ptr dword, \
|
|
pwc: dword, \
|
|
pbAccel: ptr dword >
|
|
local pbacceltmp : dword ;1 if all glyph bits have been gotten
|
|
; so far, 0 if not
|
|
|
|
mov eax, pThis ; (eax) = ptr to RFONTOBJ
|
|
mov pbacceltmp,1 ; set bAccel to true (all glyph bits
|
|
; realized so far)
|
|
;*486 pipelining
|
|
mov eax, [eax].prfnt ; (eax) = ptr to RFONT
|
|
mov esi, pwc ; pointer to wchar data
|
|
;*486 pipelining
|
|
mov eax, [eax].wcgp ; (eax) = ptr to wcgp
|
|
mov edi, pgp ; pointer to glyphpos array to fill
|
|
;*486 pipelining
|
|
lea ebx, [eax].agprun ; (ebx) = ptr to first wcgp run
|
|
;*486 pipelining
|
|
push ebp ;*486 pipelining
|
|
mov ecx, [ebx].wcLow ; index of start of run
|
|
mov edx, [ebx].cGlyphs ; # of glyphs in run
|
|
mov ebx, [ebx].apgd ; pointer to run's pointers to cached
|
|
; glyphdata
|
|
|
|
mov ebp,c_ ; we'll use EBP for the glyph count
|
|
; ***stack frame no longer available***
|
|
|
|
;--------------------------------------------------------------------------
|
|
; Fast two-glyphs-at-a-time Pentium pipe-lined loop
|
|
;
|
|
; The philosophy of this loop is that for the vast majority of the time,
|
|
; all the glyphs will be in the proper range, have cached glyphdata, and
|
|
; have cached glyphbits -- and it takes advantage of that to better make
|
|
; use of both Pentium pipes by doing two glyphs at once. If one of those
|
|
; conditions fail, it converts to the single-glyph-at-a-time loop when
|
|
; that happens.
|
|
;
|
|
; Invariants:
|
|
; (esi) = ptr to 1st wchar
|
|
; (edi) = ptr to pgp
|
|
; (ecx) = ptr to 2nd wchar
|
|
; (ecx) = wcLow of current run
|
|
; (edx) = cGlyphs of current run
|
|
; (ebp) = count of glyphs remaining
|
|
; [esp] = wcLow of current run
|
|
|
|
cmp ecx, FAST_WCHAR_BASE ; fast loop handles wcLow values only
|
|
jne gmp_slow_loop_top ; of 32
|
|
|
|
dec ebp ; pre-decrement count
|
|
jz gmp_slow_loop_top ; only one character. it's okay to
|
|
; pop this through to gmp_slow_loop_top
|
|
; with a zero count -- it's effectively
|
|
; the same as a one count
|
|
|
|
push ecx ; wcLow is now at [esp]
|
|
|
|
gmp_fast_loop_top:
|
|
mov eax, [esi] ; 1U (eax) = first two glyphs
|
|
add edi, 2*SIZE_GLYPHPOS ; 1V each iteration does two glyphpos's.
|
|
; we do this now to eat up a free V
|
|
; pipe instruction
|
|
mov ecx, eax ; 1U
|
|
add esi, 4 ; 1V each iteration does two wchars.
|
|
; we do this now to eat up a free V
|
|
; pipe instruction
|
|
shr ecx, 16 ; 1U (ecx) = 2nd wchar, zero extended
|
|
and eax, 0ffffh ; 1V (eax) = 1st wchar, zero extended
|
|
|
|
sub eax, FAST_WCHAR_BASE ; 1U get index relative to current base
|
|
sub ecx, FAST_WCHAR_BASE ; 1V get index relative to current base
|
|
|
|
cmp eax, edx ; 1U is 1st wchar in this run?
|
|
jae gmp_restart_in_slow_loop; 1V wrong run, exit fast loop
|
|
cmp ecx, edx ; 1U is 2nd wchar in this run?
|
|
jae gmp_restart_in_slow_loop; 1V wrong run, exit fast loop
|
|
|
|
mov eax, [ebx+4*eax] ; 2U (eax) = ptr to 1st glyphdata
|
|
mov ecx, [ebx+4*ecx] ; 2V (ecx) = ptr to 2nd glyphdata
|
|
; (could be 3V if in same cache
|
|
; bank)
|
|
|
|
test eax, eax ; 1U is 1st cached glyphdata there?
|
|
jz gmp_restart_in_slow_loop; 1V no glyphdata, exit fast loop
|
|
test ecx, ecx ; 1U is 2nd cached glyphdata there?
|
|
jz gmp_restart_in_slow_loop; 1V no glyphdata, exit fast loop
|
|
|
|
cmp dword ptr [eax].gd_gdf, 0 ; 2U are 1st glyph bits in cache?
|
|
je gmp_restart_in_slow_loop ; 1V no, go get them
|
|
cmp dword ptr [ecx].gd_gdf, 0 ; 2U are 2nd glyph bits in cache?
|
|
je gmp_restart_in_slow_loop ; 1V no, go get them
|
|
|
|
mov [edi-2*SIZE_GLYPHPOS].gp_pgdf, eax
|
|
; 1U set ptr to glyphdata in glyphpos
|
|
mov eax, [eax].gd_hg ; 1V read 1st glyph handle
|
|
|
|
mov [edi-1*SIZE_GLYPHPOS].gp_pgdf, ecx
|
|
; 1U set ptr to glyphdata in glyphpos
|
|
mov ecx, [ecx].gd_hg ; 1V read 2nd glyph handle
|
|
|
|
mov [edi-2*SIZE_GLYPHPOS].gp_hg,eax ; 1U set handle in glyphpos
|
|
mov [edi-1*SIZE_GLYPHPOS].gp_hg,ecx ; 1V set handle in glyphpos
|
|
|
|
sub ebp, 2 ; 1U each iteration does two glyphs
|
|
jg gmp_fast_loop_top ; 1V more loops to do
|
|
pop ecx ; account for pushed wcLow
|
|
jz gmp_slow_loop_top ; odd number of glyphs, handle last one
|
|
|
|
pop ebp ; ***stack frame available***
|
|
mov ebx,pbaccel ; where we'll store whether all glyph
|
|
; bits found
|
|
mov eax, 1 ; success
|
|
mov [ebx], 1 ; success
|
|
|
|
stdRET xGetGlyphMetricsPlus
|
|
|
|
;--------------------------------------------------------------------------
|
|
; Not-so-fast one-glyph-at-a-time loop
|
|
;
|
|
; Invariants:
|
|
; (esi) = ptr to wchar
|
|
; (edi) = ptr to pgp
|
|
; (ebx) = ptr to base of current run
|
|
; (ecx) = wcLow of current run
|
|
; (edx) = cGlyphs of current run
|
|
; (ebp) = count of glyphs remaining
|
|
|
|
gmp_restart_in_slow_loop:
|
|
pop ecx ; (ecx) = wcLow of current run
|
|
inc ebp ; account for fast-loop preadjustments
|
|
sub edi, 2*SIZE_GLYPHPOS
|
|
sub esi, 4
|
|
|
|
gmp_slow_loop_top:
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = wchar, zero extended
|
|
|
|
sub eax, ecx ; get index relative to current run base
|
|
cmp eax, edx ; is wchar in this run?
|
|
jae short gmp_find_run ; wrong run, better go get right one
|
|
|
|
gmp_run_found:
|
|
mov eax, [ebx+4*eax] ; (ecx) = ptr to glyphdata
|
|
|
|
|
|
;
|
|
; Invariants:
|
|
; (esi, edi, ebx, ecx, edx) as above at loop top
|
|
; (eax) = ptr to glyphdata
|
|
;
|
|
gmp_default_found:
|
|
and eax, eax ; is cached glyphdata there?
|
|
jz gmp_get_glyph ; no glyphdata, better go get one
|
|
|
|
;
|
|
; Here, we are assured that the glyphdata is present in the cache
|
|
;
|
|
gmp_glyph_found:
|
|
cmp dword ptr [eax].gd_gdf, 0 ; are the glyph bits in the cache?
|
|
jz gmp_get_bits ; no, go get them
|
|
|
|
;
|
|
; Here, we have tried to get the glyphbits in the cache
|
|
;
|
|
gmp_got_bits:
|
|
mov [edi].gp_pgdf, eax ; set ptr to glyphdata in glyphpos
|
|
mov eax, [eax].gd_hg
|
|
mov [edi].gp_hg, eax ; set hg in glyphpos
|
|
|
|
|
|
add edi, SIZE_GLYPHPOS ; next glyphpos to fill in
|
|
add esi, 2 ; next wchar to look up
|
|
|
|
dec ebp ; any more glyphs?
|
|
jg gmp_slow_loop_top ; must be 'greater than' check
|
|
|
|
pop ebp ; ***stack frame available***
|
|
|
|
mov ebx,pbaccel ; where we'll store whether all glyph bits found
|
|
mov eax,pbacceltmp ; 0 if not all found, 1 if all found
|
|
mov [ebx],eax ; return whether we found all glyph bits or not
|
|
|
|
mov eax, 1 ; success
|
|
stdRET xGetGlyphMetricsPlus
|
|
|
|
|
|
|
|
;=======================================================================
|
|
; We got here because the current run does not contain the wchar we're
|
|
; interested in. Note that the following invariants must hold when
|
|
; we re-enter the loop (starred items must hold on entry, as well):
|
|
; (esi) = ptr to wchar*
|
|
; (edi) = ptr to pgp*
|
|
; (ebx) = ptr to apgd of new run
|
|
; (ecx) = wcLow of new run
|
|
; (edx) = cGlyphs of new run
|
|
; (eax) = ptr to glyphdata
|
|
; (ebp) = count of glyphs remaining*
|
|
;=======================================================================
|
|
align 4
|
|
gmp_find_run:
|
|
push ebp ; preserve count of remaining glpyhs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = current wchar
|
|
mov ebx, pThis
|
|
|
|
stdcall xprunFindRunRFONTOBJ, <ebx, eax>
|
|
|
|
pop ebp ; <ebp> = glyph count
|
|
; ***stack frame no longer available***
|
|
mov ecx, [eax].wcLow ; index of start of new run
|
|
mov edx, [eax].cGlyphs ; # of glyphs in new run
|
|
mov ebx, [eax].apgd ; pointer to new run's pointers to
|
|
; cached glyphdata
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = current wchar
|
|
sub eax, ecx ; get index relative to new run base
|
|
cmp eax, edx ; is wchar in this run?
|
|
jb gmp_run_found ; yes, run with it
|
|
; not in any run; use default character
|
|
push ebp ; preserve count of remaining glyphs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
|
|
ifdef FE_SB
|
|
push ebx
|
|
push ecx
|
|
push edx
|
|
mov eax, pThis ; (eax) = pointer to RFONTOBJ
|
|
lea ebx, pbacceltmp ; (ebx) = pointer to pbacceltmp
|
|
; (esi) = pointer to current wchar
|
|
stdcall xwpgdGetLinkMetricsPlusRFONTOBJ,<eax,esi,ebx>
|
|
pop edx
|
|
pop ecx
|
|
pop ebx ; (eax) is now proper wpgd
|
|
else
|
|
mov eax,pThis
|
|
push ecx
|
|
push edx
|
|
stdcall xpgdDefault, <eax> ; eax = ptr to default character
|
|
pop edx
|
|
pop ecx
|
|
endif
|
|
pop ebp ; <ebp> = glyph count
|
|
; ***stack frame no longer available***
|
|
|
|
jmp gmp_default_found ; go with the default character
|
|
|
|
|
|
;=======================================================================
|
|
; We got here because the glyph pointer in the wcgp run was null, meaning
|
|
; we don't yet have the metrics for this glyph. Note that the following
|
|
; invariants must be true on exit (starred items must hold on entry, as
|
|
; well):
|
|
; (esi) = ptr to wchar*
|
|
; (edi) = ptr to pgp*
|
|
; (ebx) = ptr to apgd of new run*
|
|
; (ecx) = wcLow of new run*
|
|
; (edx) = cGlyphs of new run*
|
|
; (eax) = ptr to glyphdata
|
|
; (ebp) = count of glyphs remaining*
|
|
;=======================================================================
|
|
align 4
|
|
gmp_get_glyph:
|
|
push ebp ; preserve count of remaining glpyhs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
|
|
push ebx
|
|
push edx
|
|
push ecx
|
|
|
|
sub eax, eax
|
|
mov ax, [esi] ; (eax) = wchar
|
|
mov edx, eax ; set aside wchar
|
|
sub eax, ecx ; (eax) = index into run
|
|
lea ebx, [ebx+4*eax] ; (ebx) = ptr to entry
|
|
mov ecx,pThis
|
|
stdcall xInsertMetricsPlusRFONTOBJ, <ecx, ebx, edx>
|
|
pop ecx
|
|
pop edx
|
|
and eax, eax ; were we able to get the glyph metrics?
|
|
jz short gmp_failed ; no
|
|
|
|
mov eax, [ebx] ; get ptr to glyphdata from it
|
|
|
|
pop ebx
|
|
|
|
pop ebp ; <ebp> = glyph count
|
|
; ***stack frame no longer available***
|
|
jmp gmp_glyph_found
|
|
|
|
gmp_failed:
|
|
pop ebx
|
|
|
|
pop eax ; clear glyph count from stack
|
|
pop eax ; clear pushed stack frame pointer from stack
|
|
|
|
sub eax, eax ;failure
|
|
stdRET xGetGlyphMetricsPlus
|
|
|
|
;=======================================================================
|
|
; We get here if we need to try to load the bits for the glyph we're
|
|
; interested in (because the bits havene't been realized yet). We only
|
|
; even bother to try if all bits have successfully been realized so far,
|
|
; because it's only useful to realize glyphs if we can get all of them.
|
|
; Note that the following invariants must be true on both entry and exit.
|
|
; (esi) = ptr to wchar
|
|
; (edi) = ptr to pgp
|
|
; (ebx) = ptr to apgd of new run
|
|
; (ecx) = wcLow of new run
|
|
; (edx) = cGlyphs of new run
|
|
; (eax) = ptr to glyphdata
|
|
; (ebp) = count of glyphs remaining
|
|
;=======================================================================
|
|
align 4
|
|
gmp_get_bits:
|
|
push ebp ; preserve count of remaining glpyhs
|
|
mov ebp,[esp+4] ; ***stack frame available***
|
|
|
|
cmp pbacceltmp,0 ;if we already failed to get glyph bits
|
|
je short got_the_bits_done ; once, no point in trying again
|
|
|
|
push ecx
|
|
mov ecx, pThis
|
|
push edx ;*486 pipelining
|
|
mov edx, [ecx].prfnt
|
|
push eax ;*486 pipelining
|
|
cmp dword ptr [edx].ulContent, FO_HGLYPHS
|
|
je short got_the_bits
|
|
|
|
sub edx,edx
|
|
cmp pwc,esi
|
|
sbb edx,-1 ; EDX == TRUE if first wc, FALSE else
|
|
stdcall xInsertGlyphbitsRFONTOBJ, <ecx, eax, edx> ;try to get the bits
|
|
|
|
and eax, eax ; did we succeed in getting the bits?
|
|
jnz short got_the_bits ; yes, we got the bits
|
|
mov pbacceltmp, eax ; didn't get the glyph (note: EAX is zero)
|
|
got_the_bits:
|
|
pop eax
|
|
pop edx
|
|
pop ecx
|
|
got_the_bits_done:
|
|
pop ebp ; <ebp> = glyph count
|
|
; ***stack frame no longer available***
|
|
jmp gmp_got_bits
|
|
|
|
|
|
stdENDP xGetGlyphMetricsPlus
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|