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.
1394 lines
48 KiB
1394 lines
48 KiB
;===============================================================================
|
|
;
|
|
; $Workfile: TEXT.ASM $
|
|
;
|
|
; Contents:
|
|
; This file contains the assembly code for the text output routine.
|
|
;
|
|
; Copyright (c) 1996, Cirrus Logic, Inc.
|
|
;
|
|
; $Log: //uinac/log/log/laguna/nt35/displays/cl546x/i386/TEXT.ASM $
|
|
;
|
|
; Rev 1.23 Jun 22 1998 11:07:36 frido
|
|
; PDR#11546. Fixed save/restore in clipping BugLoop and also
|
|
; the register increments in DrawLoop.
|
|
;
|
|
; Rev 1.22 Mar 04 1998 15:47:14 frido
|
|
; Added more shadowing.
|
|
;
|
|
; Rev 1.21 Jan 21 1998 17:12:36 frido
|
|
; Added SWAT6 switches to stripe the opaque rectangles.
|
|
;
|
|
; Rev 1.20 Jan 20 1998 11:45:12 frido
|
|
; Added shadowing for DRAWBLTDEF and BGCOLOR registers.
|
|
;
|
|
; Rev 1.19 Dec 11 1997 16:02:46 frido
|
|
; Oops...
|
|
;
|
|
; Rev 1.18 Dec 11 1997 15:41:18 frido
|
|
; PDR#10875: There was a very weird instruction in the DrawGlyph
|
|
; routine with clipped non-cacheable glyphs.
|
|
;
|
|
; Rev 1.17 Nov 03 1997 17:41:58 frido
|
|
; Added REQUIRE macros.
|
|
;
|
|
; Rev 1.16 08 Aug 1997 17:22:32 FRIDO
|
|
; Added SWAT7 switches for 8-bpp hardware bug.
|
|
;
|
|
; Rev 1.15 29 Apr 1997 16:29:40 noelv
|
|
; Merged in new SWAT code.
|
|
; SWAT:
|
|
; SWAT: Rev 1.3 24 Apr 1997 10:45:54 frido
|
|
; SWAT: NT140b09 merge.
|
|
; SWAT:
|
|
; SWAT: Rev 1.2 19 Apr 1997 16:31:54 frido
|
|
; SWAT: Added automatic include file dependencies for BUILD.EXE.
|
|
;
|
|
; Rev 1.14 08 Apr 1997 11:48:24 einkauf
|
|
;
|
|
; add call to SYNC_W_3D for MCD coordination
|
|
;
|
|
; Rev 1.13 21 Mar 1997 10:10:20 noelv
|
|
; Synced PDEV between C code and ASM code.
|
|
; Added macro to log QFREE data.
|
|
; Consolidated do_flag and sw_test_flag into a single pointer_switch flag.
|
|
;
|
|
; Rev 1.12 07 Mar 1997 09:41:02 SueS
|
|
; Added NULL_TEXTOUT flag to assembly code. Changed order of include files.
|
|
;
|
|
; Rev 1.11 05 Mar 1997 10:37:32 noelv
|
|
;
|
|
; Marked where to put tests for QFREE
|
|
;
|
|
; Rev 1.10 04 Feb 1997 12:19:28 SueS
|
|
; Added support for hardware clipping for the 5465.
|
|
;
|
|
; Rev 1.9 20 Aug 1996 11:28:52 noelv
|
|
; Bugfix release from Frido 8-19-96
|
|
;
|
|
; Rev 1.0 14 Aug 1996 17:14:38 frido
|
|
; Initial revision.
|
|
;
|
|
; Rev 1.8 25 Jul 1996 15:49:52 bennyn
|
|
; Modified to support DirectDraw
|
|
;
|
|
; Rev 1.7 03 May 1996 15:24:24 noelv
|
|
;
|
|
; Added switch to turn font caching on and off.
|
|
;
|
|
; Rev 1.6 01 May 1996 11:06:46 bennyn
|
|
;
|
|
; Modified for NT 4.0
|
|
;
|
|
; Rev 1.5 04 Apr 1996 13:22:18 noelv
|
|
; Frido version 26
|
|
;
|
|
; Rev 1.14 28 Mar 1996 23:38:52 frido
|
|
; Fixed drawing of partially left-clipped glyphs.
|
|
;
|
|
; Rev 1.13 04 Mar 1996 20:23:50 frido
|
|
; Cached grCONTROL register.
|
|
;
|
|
; Rev 1.12 29 Feb 1996 20:21:32 frido
|
|
; Fixed some pointer updates.
|
|
;
|
|
; Rev 1.11 28 Feb 1996 22:40:22 frido
|
|
; Added Optimize.h.
|
|
;
|
|
; Rev 1.10 27 Feb 1996 23:52:40 frido
|
|
; Removed bug in DrawGlyph with non clipped characters.
|
|
;
|
|
; Rev 1.9 27 Feb 1996 16:39:54 frido
|
|
; Added device bitmap store/restore.
|
|
;
|
|
; Rev 1.8 24 Feb 1996 01:22:58 frido
|
|
; Added device bitmaps.
|
|
;
|
|
; Rev 1.7 19 Feb 1996 06:24:28 frido
|
|
; Removed extraneous debugging code.
|
|
; Added comments.
|
|
;
|
|
; Rev 1.6 17 Feb 1996 21:46:44 frido
|
|
; Changed FIFO_CHECK into broken_FIFO.
|
|
;
|
|
; Rev 1.5 08 Feb 1996 00:03:54 frido
|
|
; Added i386\ to include files.
|
|
;
|
|
; Rev 1.4 06 Feb 1996 16:13:16 frido
|
|
; Added check for invalid rectangle during clippped opaquing.
|
|
;
|
|
; Rev 1.3 03 Feb 1996 12:17:28 frido
|
|
; Added text clipping.
|
|
;
|
|
; Rev 1.2 25 Jan 1996 22:14:10 frido
|
|
; Removed extraneous push/pop instructions.
|
|
;
|
|
; Rev 1.1 25 Jan 1996 12:42:38 frido
|
|
; Added reinitialization of font cache after mode switch.
|
|
;
|
|
; Rev 1.0 24 Jan 1996 23:13:44 frido
|
|
; Initial release.
|
|
;
|
|
;===============================================================================
|
|
|
|
.386
|
|
.MODEL FLAT, STDCALL
|
|
|
|
.NOLIST
|
|
INCLUDE i386\Macros.inc
|
|
INCLUDE i386\WinNT.inc
|
|
INCLUDE i386\Font.inc
|
|
INCLUDE Optimize.h
|
|
INCLUDE i386\Laguna.inc
|
|
INCLUDE Swat.h
|
|
COMMENT ! ;automatic include file dependencies for BUILD.EXE
|
|
#include "i386\Macros.inc"
|
|
#include "i386\WinNT.inc"
|
|
#include "i386\Font.inc"
|
|
#include "Optimize.h"
|
|
#include "i386\Laguna.inc"
|
|
#include "SWAT.h"
|
|
!
|
|
.LIST
|
|
|
|
IF USE_ASM
|
|
|
|
.DATA
|
|
|
|
IF POINTER_SWITCH_ENABLED
|
|
EXTERN pointer_switch: DWORD
|
|
ENDIF
|
|
|
|
IF LOG_QFREE
|
|
EXTERN QfreeData: DWORD
|
|
ENDIF
|
|
|
|
.CODE
|
|
|
|
;
|
|
; Function prototypes.
|
|
;
|
|
AddToFontCacheChain PROTO PROC,
|
|
ppdev :DWORD,
|
|
pfo :DWORD,
|
|
pfc :DWORD
|
|
AllocGlyph PROTO PROC,
|
|
pfc :DWORD,
|
|
pgb :DWORD,
|
|
pgc :DWORD
|
|
i386DrvTextOut PROTO PROC,
|
|
pso :DWORD,
|
|
pstro :DWORD,
|
|
pfo :DWORD,
|
|
pco :DWORD,
|
|
prclExtra :DWORD,
|
|
prclOpaque :DWORD,
|
|
pboFore :DWORD,
|
|
pboOpaque :DWORD,
|
|
pptlBrush :DWORD,
|
|
mix :DWORD
|
|
EngTextOut PROTO PROC,
|
|
pso :DWORD,
|
|
pstro :DWORD,
|
|
pfo :DWORD,
|
|
pco :DWORD,
|
|
prclExtra :DWORD,
|
|
prclOpaque :DWORD,
|
|
pboFore :DWORD,
|
|
pboOpaque :DWORD,
|
|
pptlBrush :DWORD,
|
|
mix :DWORD
|
|
DrvDestroyFont PROTO PROC,
|
|
pfo :DWORD
|
|
bCreateScreenFromDib PROTO PROC,
|
|
ppdev :DWORD,
|
|
pdsurf :DWORD
|
|
StripePatBlt PROTO PROC,
|
|
ppdev :DWORD,
|
|
x :DWORD,
|
|
y :DWORD,
|
|
nWidth :DWORD,
|
|
nHeight :DWORD
|
|
ifdef WINNT_VER40
|
|
Sync_w_3d_proc PROTO PROC,
|
|
ppdev :PTR PDEV
|
|
endif
|
|
|
|
|
|
;
|
|
; Stack frame for DrvTextOut.
|
|
;
|
|
espPTR = 0
|
|
frmPTR = 0
|
|
pso_ TEXTEQU <DWORD PTR [esp + 4 + espPTR]>
|
|
pstro_ TEXTEQU <DWORD PTR [esp + 8 + espPTR]>
|
|
pfo_ TEXTEQU <DWORD PTR [esp + 12 + espPTR]>
|
|
pco_ TEXTEQU <DWORD PTR [esp + 16 + espPTR]>
|
|
prclExtra_ TEXTEQU <DWORD PTR [esp + 20 + espPTR]>
|
|
prclOpaque_ TEXTEQU <DWORD PTR [esp + 24 + espPTR]>
|
|
pboFore_ TEXTEQU <DWORD PTR [esp + 28 + espPTR]>
|
|
pboOpaque_ TEXTEQU <DWORD PTR [esp + 32 + espPTR]>
|
|
pptlBrush_ TEXTEQU <DWORD PTR [esp + 36 + espPTR]>
|
|
mix_ TEXTEQU <DWORD PTR [esp + 40 + espPTR]>
|
|
|
|
OPTION PROLOGUE:None
|
|
OPTION EPILOGUE:None
|
|
|
|
DrvTextOut PROC PUBLIC,
|
|
pso :DWORD,
|
|
pstro :DWORD,
|
|
pfo :DWORD,
|
|
pco :DWORD,
|
|
prclExtra :DWORD,
|
|
prclOpaque :DWORD,
|
|
pboFore :DWORD,
|
|
pboOpaque :DWORD,
|
|
pptlBrush :DWORD,
|
|
mix :DWORD
|
|
|
|
IF NULL_TEXTOUT
|
|
cmp pointer_switch, 0 ; Has the cursor been moved to (0,0)?
|
|
je NotNull ; No - continue on
|
|
mov eax, 1 ; Make GDI think we succeeded
|
|
ret 40 ; Return and release stack frame
|
|
NotNull:
|
|
ENDIF
|
|
|
|
push_ edi
|
|
mov edi, [pfo_] ;EDI holds pointer to font
|
|
ASSUME edi:PTR FONTOBJ
|
|
mov ecx, [pso_] ;ECX holds pointer to destination
|
|
ASSUME ecx:PTR SURFOBJ
|
|
push_ esi
|
|
push_ ebp
|
|
push_ ebx
|
|
save_ 1 ;save current stack state
|
|
mov edx, [pstro_] ;EDX holds pointer to string
|
|
ASSUME edx:PTR STROBJ
|
|
mov ebx, [ecx].dhsurf ;get the pointer to the device bitmap
|
|
ASSUME ebx:PTR DSURF
|
|
mov esi, [edi].pvConsumer ;ESI holds pointer to font cache
|
|
ASSUME esi:PTR FONTCACHE
|
|
cmp [ecx].iType, STYPE_DEVBITMAP
|
|
;are we drawing in a device bitmap?
|
|
mov ebp, [ecx].dhpdev ;EBP holds pointer to device
|
|
ASSUME ebp:PTR PDEV
|
|
jne @F ;no
|
|
|
|
ifdef WINNT_VER40
|
|
;SYNC_W_3D macro equivalent
|
|
cmp [ebp].NumMCDContexts, 0 ; is MCD alive?
|
|
jle Sync_end ; no
|
|
push ecx ; save
|
|
push edx ; save
|
|
push ebp ; input to Sync_w_3d_proc
|
|
call Sync_w_3d_proc
|
|
pop edx ; restore
|
|
pop ecx ; restore
|
|
Sync_end:
|
|
endif
|
|
|
|
mov ebx, [ebx].pso ;get the handle to the DIB
|
|
or ebx, ebx ;is the device bitmap a DIB?
|
|
jz @F ;no
|
|
INVOKE bCreateScreenFromDib, ;copy the DIB to off-screen
|
|
ebp,
|
|
ebx
|
|
or eax, eax
|
|
jz Simulate ;failure
|
|
@@: cmp [ebp].UseFontCache, 0 ;Is font caching enabled?
|
|
je FontNotCached ;no, use C code.
|
|
or esi, esi ;is font cache allocated?
|
|
jz NewFont ;no, new font
|
|
cmp esi, -1 ;is font uncacheable?
|
|
je FontNotCached ;yes
|
|
cmp [esi].ppdev, ebp ;font cached in current device?
|
|
mov eax, [ebp].ulFontCount
|
|
jne FontNotCached ;no
|
|
cmp [esi].ulFontCount, eax ;device count still matches?
|
|
jne DestroyFont ;no, recache font
|
|
|
|
;
|
|
; We have a font that is still cached.
|
|
;
|
|
FontCached:
|
|
mov ebx, [pco_] ;EBX holds pointer to clip object
|
|
ASSUME ebx:PTR CLIPOBJ
|
|
mov eax, [pboFore_] ;EAX has foreground brush
|
|
ASSUME eax:PTR BRUSHOBJ
|
|
mov edx, [pboOpaque_] ;EDX has background brush
|
|
ASSUME edx:PTR BRUSHOBJ
|
|
or ebx, ebx ;clip object present?
|
|
jz @F ;no
|
|
cmp [ebx].iDComplexity, DC_TRIVIAL
|
|
;trivial clipping?
|
|
jne CheckClipping ;no, check for clipping
|
|
@@: cmp [ebp].iBytesPerPixel, 2
|
|
mov ebx, ebp ;store pointer to PDEV structure
|
|
mov ebp, [ebp].pLgREGS_real ;EBP holds pointer to Laguna registers
|
|
ASSUME ebp:NOTHING
|
|
mov eax, [eax].iSolidColor ;get foreground color
|
|
ASSUME eax:NOTHING
|
|
mov edx, [edx].iSolidColor ;get background color
|
|
ASSUME edx:NOTHING
|
|
ja @F ;no color translation needed
|
|
je Xlate16 ;16-bpp
|
|
mov ah, al ;expand 8-bpp into 16-bit
|
|
mov dh, dl
|
|
Xlate16:
|
|
mov ecx, eax ;expand 16-bpp into 32-bit
|
|
shl eax, 16
|
|
mov esi, edx
|
|
shl edx, 16
|
|
or eax, ecx
|
|
or edx, esi
|
|
|
|
@@: ASSUME ebx:PTR PDEV
|
|
REQUIRE 4, ebx
|
|
cmp [ebx].shadowFGCOLOR, eax
|
|
je @F
|
|
mov [ebp + grOP_opFGCOLOR], eax
|
|
mov [ebx].shadowFGCOLOR, eax;store foreground color in Laguna
|
|
@@: mov eax, [pso_] ;EAX holds pointer to destination
|
|
ASSUME eax:PTR SURFOBJ
|
|
cmp [ebx].shadowBGCOLOR, edx
|
|
je @F
|
|
mov [ebp + grOP_opBGCOLOR], edx
|
|
mov [ebx].shadowBGCOLOR, edx;store background color in Laguna
|
|
@@: xor edx, edx ;zero x/y offset
|
|
cmp [eax].iType, STYPE_DEVBITMAP
|
|
mov eax, [eax].dhsurf ;get pointer to device bitmap
|
|
ASSUME eax:PTR DSURF
|
|
jne @F ;target is not a device bitmap
|
|
mov edx, [eax].packedXY ;get packed x/y offset of device bitmap
|
|
@@: mov eax, [prclOpaque_] ;EAX holds opaquing rectangle
|
|
ASSUME eax:PTR RECTL
|
|
mov [mix_], edx ;store x/y offset into mix variable
|
|
test eax, eax ;opaquing rectangle present?
|
|
jz SkipOpaque ;no
|
|
ASSUME ebx:PTR PDEV
|
|
REQUIRE 7, ebx
|
|
cmp [ebx].shadowDRAWBLTDEF, SOLID_COLOR_FILL
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], SOLID_COLOR_FILL
|
|
mov [ebx].shadowDRAWBLTDEF, SOLID_COLOR_FILL
|
|
@@: ;use solid background fill
|
|
mov edi, [eax].left ;get rectangle coordinates
|
|
mov ecx, [eax].top
|
|
mov edx, [eax].right
|
|
mov eax, [eax].bottom
|
|
sub edx, edi ;convert to size
|
|
sub eax, ecx
|
|
IF SWAT6
|
|
push_ ebx
|
|
mov ebx, [mix_]
|
|
and ebx, 0000FFFFh
|
|
add edi, ebx
|
|
mov ebx, [mix_]
|
|
shr ebx, 16
|
|
add ecx, ebx
|
|
pop_ ebx
|
|
INVOKE StripePatBlt, ebx, edi, ecx, edx, eax
|
|
ELSE
|
|
shl ecx, 16 ;pack x/y
|
|
add edi, [mix_] ;add x/y offset to left
|
|
shl eax, 16
|
|
add ecx, edi
|
|
or eax, edx
|
|
mov [ebp + grOP0_opRDRAM], ecx
|
|
;draw rectangle
|
|
mov [ebp + grBLTEXT_EX], eax
|
|
ENDIF
|
|
|
|
SkipOpaque:
|
|
mov ax, [ebp + grCONTROL]
|
|
mov edi, [pfo_] ;EDI holds pointer to font
|
|
ASSUME edi:PTR FONTOBJ
|
|
or eax, SWIZ_CNTL ;enable bit mirroring
|
|
cmp [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], CACHE_EXPAND_XPAR
|
|
mov [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
@@: ;expand characters from cache
|
|
mov [ebp + grCONTROL], ax
|
|
mov edx, ebx ;store pointer to PDEV structure
|
|
mov ebx, [pstro_] ;EBX holds pointer to string
|
|
ASSUME ebx:PTR STROBJ
|
|
mov edi, [edi].pvConsumer ;EDI holds pointer to font cache
|
|
ASSUME edi:PTR FONTCACHE
|
|
|
|
;
|
|
; We are now ready to start the main font cache loop. We first determine if we
|
|
; need to enumerate the GLYPHPOS arrays or not. Then we start the main loop,
|
|
; which is a very short simple loop. For each glyph that falls in the caching
|
|
; range, we check if the glyph is cached. If so, we just copy the glyph from
|
|
; off-screen memory. If the glyph is not cached, we check if it is small enough
|
|
; to fit in a tile and if so, we cache it off-screen and than copy itto its
|
|
; destination. If the glyph is too large, we draw it directly on screen.
|
|
;
|
|
enter_ 16 ;create stack frame
|
|
bMoreGlyphs_ TEXTEQU <DWORD PTR [esp + 0 + frmPTR]>
|
|
ulCharInc_ TEXTEQU <DWORD PTR [esp + 4 + frmPTR]>
|
|
dwControl_ TEXTEQU <DWORD PTR [esp + 8 + frmPTR]>
|
|
pdev_ TEXTEQU <DWORD PTR [esp + 12 + frmPTR]>
|
|
save_ 2 ;store state of stack
|
|
mov [pdev_], edx
|
|
|
|
mov [dwControl_], eax
|
|
mov eax, [ebx].ulCharInc ;copy ulCharInc from string object
|
|
cmp [ebx].pgp, 0
|
|
mov [ulCharInc_], eax
|
|
je Enumerate ;there is more than one array
|
|
mov ecx, [ebx].cGlyphs ;get number of glyphs to draw
|
|
mov ebx, [ebx].pgp ;get pointer to glyph position array
|
|
ASSUME ebx:PTR GLYPHPOS
|
|
mov [bMoreGlyphs_], 0 ;no more glyphs to enumerate
|
|
|
|
MainLoop:
|
|
or ecx, ecx ;any glyphs to draw?
|
|
je SkipLoop ;no
|
|
mov eax, [ebx].ptl.x ;get coordinates of first glyph
|
|
mov edx, [ebx].ptl.y
|
|
GlyphLoop:
|
|
push_ ecx
|
|
mov ecx, [ebx].hg ;get the glyph handle
|
|
cmp [ulCharInc_], 0 ;fixed font?
|
|
jne @F ;no
|
|
mov eax, [ebx].ptl.x ;get coordinates for glyph
|
|
mov edx, [ebx].ptl.y
|
|
@@: shl ecx, 4 ;build index into font cache array
|
|
cmp ecx, MAX_GLYPHS * 16 ;glyph out of range?
|
|
jnl DrawGlyph ;yes, draw it directly
|
|
save_ 9
|
|
mov esi, [edi + ecx*1].aGlyphs.xyPos
|
|
;get off-screen location of glyph
|
|
lea ecx, [edi + ecx*1].aGlyphs
|
|
;load address of cache slot
|
|
ASSUME ecx:PTR GLYPHCACHE
|
|
or esi, esi ;is the glyph already cached?
|
|
jnz @F ;yes
|
|
mov esi, [ebx].pgdf ;cache the glyph
|
|
ASSUME esi:PTR GLYPHDEF
|
|
push eax
|
|
push edx
|
|
push ecx
|
|
INVOKE AllocGlyph,
|
|
edi,
|
|
[esi].pgb,
|
|
ecx
|
|
pop ecx
|
|
pop edx
|
|
pop eax
|
|
mov esi, [ecx].xyPos ;get off-screen location of glyph
|
|
@@: cmp [ecx].cSize, 0 ;is this an empty glyph?
|
|
jl DrawGlyph ;no, in fact it is non-cacheable
|
|
jz Increment ;yes, skip it
|
|
push_ edx
|
|
push_ eax
|
|
add edx, [ecx].ptlOrigin.y ;add origin of glyph to coordinates
|
|
add eax, [ecx].ptlOrigin.x
|
|
shl edx, 16 ;pack coordinates
|
|
or edx, eax
|
|
mov eax, [pdev_]
|
|
ASSUME eax:PTR PDEV
|
|
REQUIRE 7, eax
|
|
mov [ebp + grOP2_opMRDRAM], esi
|
|
;copy the glyph from off-screen memory
|
|
mov esi, [mix_] ;get x/y offset
|
|
mov eax, [ecx].cSize
|
|
add edx, esi ;add x/y offset
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
mov [ebp + grBLTEXT_EX], eax
|
|
pop_ eax
|
|
pop_ edx
|
|
|
|
Increment:
|
|
add eax, [ulCharInc_] ;add the x-increment
|
|
pop_ ecx
|
|
add ebx, SIZEOF GLYPHPOS ;next glyph
|
|
dec ecx
|
|
jnz GlyphLoop
|
|
SkipLoop:
|
|
cmp [bMoreGlyphs_], 0 ;more arrays to draw?
|
|
jne Enumerate ;yes
|
|
mov ecx, [dwControl_]
|
|
leave_ 16 ;remove stack frame
|
|
and ecx, NOT SWIZ_CNTL ;reset bit mirroring
|
|
mov eax, 1 ;return TRUE
|
|
mov [ebp + grCONTROL], cx
|
|
pop_ ebx
|
|
pop_ ebp
|
|
pop_ esi
|
|
pop_ edi
|
|
ret 40
|
|
|
|
;
|
|
; Draw the glyph directly to screen.
|
|
;
|
|
DrawGlyph:
|
|
load_ 9
|
|
mov esi, [ebx].pgdf ;ESI holds pointer to GLYPHDEF
|
|
ASSUME esi:PTR GLYPHDEF
|
|
push_ eax
|
|
push_ edx
|
|
mov esi, [esi].pgb ;ESI holds pointer to GLYPHBITS
|
|
ASSUME esi:PTR GLYPHBITS
|
|
push_ edi
|
|
push_ ebx
|
|
mov ebx, [pdev_]
|
|
ASSUME ebx:PTR PDEV
|
|
|
|
mov ecx, [esi].sizlBitmap._cy
|
|
;get height of glyph
|
|
add edx, [esi].ptlOrigin.y ;add y-origin to coordinate
|
|
shl ecx, 16
|
|
jz SkipDraw ;if zero, skip
|
|
shl edx, 16
|
|
add eax, [esi].ptlOrigin.x ;add x-origin to coordinate
|
|
mov edi, [esi].sizlBitmap._cx
|
|
;get width of glyph
|
|
or edx, eax
|
|
or ecx, edi
|
|
add edx, [mix_] ;add x/y offset
|
|
lea esi, [esi].aj ;ESI points to bits
|
|
ASSUME esi:NOTHING
|
|
|
|
IF SWAT7
|
|
add edi, 7 ;convert width into byte delta
|
|
REQUIRE 9, ebx
|
|
cmp [ebx].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], TEXT_EXPAND_XPAR
|
|
mov [ebx].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR
|
|
@@: shr edi, 3
|
|
mov DWORD PTR [ebp + grOP2_opMRDRAM], 0
|
|
cmp cx, 64 ;bug when doing 64 < width < 128
|
|
jbe SkipBug
|
|
cmp cx, 128
|
|
jae SkipBug
|
|
push ecx ;save registers
|
|
push edx
|
|
push esi
|
|
mov cx, 64 ;1st passs, 64 pixels
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
mov [ebp + grBLTEXT_EX], ecx
|
|
shr ecx, 16 ;get height into ECX
|
|
@@: REQUIRE 2, ebx
|
|
mov eax, [esi][0] ;transfer 64 pixels
|
|
mov edx, [esi][4]
|
|
mov [ebp + grHOSTDATA][0], eax
|
|
mov [ebp + grHOSTDATA][4], edx
|
|
add esi, edi ;next glyph line
|
|
dec ecx
|
|
jnz @B
|
|
pop esi
|
|
pop edx
|
|
add esi, 64 / 8 ;8 bytes already done
|
|
pop ecx
|
|
add edx, 64 ;offset to next 64 pixels
|
|
sub ecx, 64
|
|
SkipBug:
|
|
REQUIRE 5, ebx
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
mov edx, ecx ;get number of pixels into EDX
|
|
mov [ebp + grBLTEXT_EX], ecx
|
|
and edx, 0000FFFFh
|
|
shr ecx, 16 ;get height back
|
|
mov ebx, [pdev_]
|
|
ASSUME ebx:PTR PDEV
|
|
cmp edx, 8 ;test width
|
|
jbe Draw1Byte ;glyph located in 1 byte
|
|
cmp edx, 16
|
|
jbe Draw2Bytes ;glyph located in 2 bytes
|
|
cmp edx, 24
|
|
jbe Draw3Bytes ;glyph located in 3 bytes
|
|
cmp edx, 32
|
|
jbe Draw4Bytes ;glyph located in 4 bytes
|
|
|
|
DrawLoop:
|
|
push edx ;store pixel count
|
|
push esi ;store current byte offset
|
|
@@: mov eax, [esi] ;get 4 bytes
|
|
add esi, 4
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
sub edx, 32 ;32 pixels done
|
|
jg @B ;still more bytes to copy
|
|
pop esi ;restore byte offset
|
|
pop edx ;restore pixel count
|
|
add esi, edi ;next glyph row
|
|
dec ecx
|
|
jnz DrawLoop
|
|
jmp SkipDraw
|
|
|
|
Draw1Byte:
|
|
mov al, [esi] ;get byte from glyph
|
|
add esi, edi
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw it
|
|
dec ecx ;next glyph row
|
|
jnz Draw1Byte
|
|
jmp SkipDraw
|
|
|
|
Draw2Bytes:
|
|
mov ax, [esi] ;get 2 bytes from glyph
|
|
add esi, edi
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph row
|
|
jnz Draw2Bytes
|
|
jmp SkipDraw
|
|
|
|
Draw4Bytes:
|
|
mov eax, [esi] ;get 4 bytes from glyph
|
|
add esi, edi
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph row
|
|
jnz Draw4Bytes
|
|
jmp SkipDraw
|
|
|
|
Draw3Bytes:
|
|
mov al, [esi + 2] ;get 3 bytes from glyph
|
|
shl eax, 16
|
|
mov ax, [esi + 0]
|
|
add esi, edi
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph row
|
|
jnz Draw3Bytes
|
|
ELSE
|
|
REQUIRE 7, ebx
|
|
cmp [ebx].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], TEXT_EXPAND_XPAR
|
|
mov [ebx].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR
|
|
@@: ;expand glyph on-screen
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
mov DWORD PTR [ebp + grOP2_opMRDRAM], 0
|
|
mov [ebp + grBLTEXT_EX], ecx
|
|
shr ecx, 16 ;get height back
|
|
cmp edi, 8 ;test width
|
|
jbe Draw1Byte ;glyph located in 1 byte
|
|
cmp edi, 16
|
|
jbe Draw2Bytes ;glyph located in 2 bytes
|
|
cmp edi, 24
|
|
jbe Draw3Bytes ;glyph located in 3 bytes
|
|
cmp edi, 32
|
|
jbe Draw4Bytes ;glyph located in 4 bytes
|
|
|
|
add edi, 7 ;byte adjust glyph width
|
|
shr edi, 3
|
|
DrawLoop:
|
|
mov edx, edi ;get width
|
|
@@: mov eax, [esi] ;get 4 bytes
|
|
add esi, 4
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
sub edx, 4 ;4 bytes done
|
|
jg @B ;still more bytes to copy
|
|
add esi, edx ;next glyph row
|
|
dec ecx
|
|
jnz DrawLoop
|
|
jmp SkipDraw
|
|
|
|
Draw1Byte:
|
|
@@: mov al, [esi] ;get byte from glyph
|
|
inc esi
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw it
|
|
dec ecx ;next glyph row
|
|
jnz @B
|
|
jmp SkipDraw
|
|
|
|
Draw2Bytes:
|
|
@@: mov ax, [esi] ;get 2 bytes from glyph
|
|
add esi, 2
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph row
|
|
jnz @B
|
|
jmp SkipDraw
|
|
|
|
Draw4Bytes:
|
|
@@: mov eax, [esi] ;get 4 bytes from glyph
|
|
add esi, 4
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph row
|
|
jnz @B
|
|
jmp SkipDraw
|
|
|
|
Draw3Bytes:
|
|
@@: mov eax, [esi] ;eax = 3210
|
|
add esi, 4
|
|
REQUIRE 4, ebx
|
|
mov [ebp + grHOSTDATA], eax ;store 210
|
|
dec ecx
|
|
jz SkipDraw
|
|
mov edx, [esi] ;edx = 7654
|
|
add esi, 4
|
|
shrd eax, edx, 24 ;eax = 6543
|
|
dec ecx
|
|
mov [ebp + grHOSTDATA], eax ;store 543
|
|
jz SkipDraw
|
|
mov eax, [esi] ;eax = ba98
|
|
add esi, 4
|
|
shrd edx, eax, 16 ;edx = 9876
|
|
dec ecx
|
|
mov [ebp + grHOSTDATA], edx ;store 876
|
|
jz SkipDraw
|
|
shr eax, 8 ;eax = xba9
|
|
dec ecx
|
|
mov [ebp + grHOSTDATA], eax ;store ba9
|
|
jnz @B
|
|
ENDIF
|
|
SkipDraw:
|
|
REQUIRE 2, ebx
|
|
cmp [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], CACHE_EXPAND_XPAR
|
|
mov [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
@@: ;enable off-screen expansion
|
|
pop_ ebx
|
|
pop_ edi
|
|
pop_ edx
|
|
pop_ eax
|
|
jmp Increment
|
|
|
|
;
|
|
; Enumerate an array of glyphs.
|
|
;
|
|
Enumerate:
|
|
load_ 2
|
|
push_ eax ;create room on stack for return
|
|
push_ eax ; parameters
|
|
mov eax, [pstro_] ;get pointer to STROBJ
|
|
mov ebx, esp ;ebx points to pgp parameter
|
|
lea ecx, [esp + 4] ;ecx points to c parameter
|
|
INVOKE STROBJ_bEnum,
|
|
eax,
|
|
ecx,
|
|
ebx
|
|
pop_ ebx ;load pgp from stack
|
|
pop_ ecx ;load c from stack
|
|
mov [bMoreGlyphs_], eax
|
|
jmp MainLoop
|
|
|
|
;
|
|
; Remove the current font from the cache. EDI holds the pointer to the font
|
|
; object.
|
|
;
|
|
DestroyFont:
|
|
load_ 1 ;retrieve stack state on entry
|
|
INVOKE DrvDestroyFont, ;destroy font
|
|
edi
|
|
jmp @F
|
|
;
|
|
; We have a new font. See if the font fits into an off-screen tile by comparing
|
|
; the bounding box to 150% of the tile size. We use 150% since we might still
|
|
; be able to cache the lowercase glyphs of larger fonts.
|
|
;
|
|
NewFont:
|
|
ASSUME edx:PTR STROBJ
|
|
mov ebx, [edx].rclBkGround.bottom
|
|
;get height of font
|
|
sub ebx, [edx].rclBkGround.top
|
|
cmp ebx, LINES_PER_TILE * 3 / 2
|
|
;test if small enough to fit in tile
|
|
jg AbortFont ;too big
|
|
|
|
ifdef WINNT_VER40
|
|
@@: INVOKE EngAllocMem, ;allocate memory for font cache
|
|
FL_ZERO_MEMORY,
|
|
SIZEOF FONTCACHE,
|
|
'XGLC'
|
|
else
|
|
@@: INVOKE LocalAlloc, ;allocate memory for font cache
|
|
LMEM_FIXED OR LMEM_ZEROINIT,
|
|
SIZEOF FONTCACHE
|
|
endif
|
|
|
|
ASSUME eax:PTR FONTCACHE
|
|
or eax, eax
|
|
jz AbortFont ;error, not enough memory
|
|
ASSUME edi:PTR FONTOBJ
|
|
mov [edi].pvConsumer, eax ;store pointer to font cache in font
|
|
ASSUME ebp:PTR PDEV
|
|
mov ebx, [ebp].ulFontCount
|
|
mov [eax].ppdev, ebp ;store pointer to device
|
|
mov [eax].ulFontCount, ebx ;store current device count
|
|
INVOKE AddToFontCacheChain,
|
|
ebp,
|
|
edi,
|
|
eax
|
|
jmp FontCached
|
|
|
|
AbortFont:
|
|
ASSUME edi:PTR FONTOBJ
|
|
mov [edi].pvConsumer, -1 ;mark the font as uncacheable
|
|
FontNotCached:
|
|
pop_ ebx ;pass through non-cache font handler
|
|
pop_ ebp
|
|
pop_ esi
|
|
pop_ edi
|
|
jmp i386DrvTextOut
|
|
|
|
Simulate:
|
|
load_ 1
|
|
mov [pso_], ebx ;save new surface object
|
|
pop ebx ;pass through engine
|
|
pop ebp
|
|
pop esi
|
|
pop edi
|
|
jmp EngTextOut
|
|
;
|
|
; We only support simple rectangle clipping in assembly.
|
|
;
|
|
CheckClipping:
|
|
ASSUME ebx:PTR CLIPOBJ
|
|
cmp [ebx].iDComplexity, DC_RECT
|
|
jne FontNotCached
|
|
DrvTextOut ENDP
|
|
|
|
;
|
|
; Right now, EAX holds the foreground brush, EBX points to the clipping object,
|
|
; EDX holds the background brush, and EBP points to the device.
|
|
;
|
|
ClipTextOut PROC
|
|
ASSUME eax:PTR BRUSHOBJ
|
|
ASSUME ebx:PTR CLIPOBJ
|
|
ASSUME edx:PTR BRUSHOBJ
|
|
ASSUME ebp:PTR PDEV
|
|
|
|
load_ 1
|
|
cmp [ebp].iBytesPerPixel, 2
|
|
push_ ebp
|
|
mov ebp, [ebp].pLgREGS_real ;EBP points to Laguna registers
|
|
ASSUME ebp:NOTHING
|
|
mov eax, [eax].iSolidColor ;get foreground color
|
|
ASSUME eax:NOTHING
|
|
mov edx, [edx].iSolidColor ;get background color
|
|
ASSUME edx:NOTHING
|
|
ja @F
|
|
je Xlate16
|
|
mov ah, al ;expand 8-bpp into 16-bit
|
|
mov dh, dl
|
|
Xlate16:
|
|
mov ecx, eax ;expand 16-bpp into 32-bit
|
|
shl eax, 16
|
|
mov esi, edx
|
|
shl edx, 16
|
|
or eax, ecx
|
|
or edx, esi
|
|
@@: pop_ ecx
|
|
ASSUME ecx:PTR PDEV
|
|
REQUIRE 4, ecx
|
|
cmp [ecx].shadowFGCOLOR, eax
|
|
je @F
|
|
mov [ebp + grOP_opFGCOLOR], eax
|
|
mov [ecx].shadowFGCOLOR, eax;store foreground color
|
|
@@: mov eax, [pso_] ;get pointer to destination
|
|
ASSUME eax:PTR SURFOBJ
|
|
cmp [ecx].shadowBGCOLOR, edx
|
|
je @F
|
|
mov [ebp + grOP_opBGCOLOR], edx
|
|
mov [ecx].shadowBGCOLOR, edx
|
|
@@: ;store background color
|
|
xor edx, edx ;zero x/y offset
|
|
cmp [eax].iType, STYPE_DEVBITMAP
|
|
mov eax, [eax].dhsurf ;get pointer to device bitmap
|
|
ASSUME eax:PTR DSURF
|
|
jne @F ;destination is not a device bitmap
|
|
mov edx, [eax].packedXY ;get x/y offset of device bitmap
|
|
@@: mov eax, [prclOpaque_] ;get pointer to opaquing rectangle
|
|
ASSUME eax:PTR RECTL
|
|
mov [mix_], edx ;store x/y offset into mix variable
|
|
push_ ecx
|
|
test eax, eax ;do we have an opaquing rectangle?
|
|
jz SkipOpaque ;no
|
|
cmp [ecx].shadowDRAWBLTDEF, SOLID_COLOR_FILL
|
|
je @F
|
|
REQUIRE 2, ecx
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], SOLID_COLOR_FILL
|
|
mov [ecx].shadowDRAWBLTDEF, SOLID_COLOR_FILL
|
|
@@: ;use a solid fill
|
|
mov esi, [mix_] ;get x/y offset
|
|
mov edi, [eax].left ;get the rectangle coordinates
|
|
mov ecx, [eax].top
|
|
mov edx, [eax].right
|
|
mov eax, [eax].bottom
|
|
cmp edi, [ebx].rclBounds.left
|
|
;clip with clipping rectangle
|
|
jg @F
|
|
mov edi, [ebx].rclBounds.left
|
|
@@: cmp ecx, [ebx].rclBounds.top
|
|
jg @F
|
|
mov ecx, [ebx].rclBounds.top
|
|
@@: cmp edx, [ebx].rclBounds.right
|
|
jl @F
|
|
mov edx, [ebx].rclBounds.right
|
|
@@: cmp eax, [ebx].rclBounds.bottom
|
|
jl @F
|
|
mov eax, [ebx].rclBounds.bottom
|
|
@@: sub edx, edi
|
|
jle SkipOpaque ;invalid width
|
|
sub eax, ecx
|
|
jle SkipOpaque ;invalid height
|
|
IF SWAT6
|
|
push esi
|
|
and esi, 0000FFFFh
|
|
add edi, esi
|
|
pop esi
|
|
shr esi, 16
|
|
add ecx, esi
|
|
mov esi, [esp]
|
|
INVOKE StripePatBlt, esi, edi, ecx, edx, eax
|
|
ELSE
|
|
shl ecx, 16 ;pack x/y
|
|
add edi, esi ;add x/y offset
|
|
shl eax, 16
|
|
add ecx, edi
|
|
or eax, edx
|
|
mov edx, [esp]
|
|
ASSUME edx:PTR PDEV
|
|
REQUIRE 5, edx
|
|
mov [ebp + grOP0_opRDRAM], ecx
|
|
;draw rectangle
|
|
mov [ebp + grBLTEXT_EX], eax
|
|
ENDIF
|
|
SkipOpaque:
|
|
pop_ ecx
|
|
ASSUME ecx:PTR PDEV
|
|
|
|
enter_ 40 ;create stack frame
|
|
bMoreGlyphs_ TEXTEQU <DWORD PTR [esp + 0 + frmPTR]>
|
|
ulCharInc_ TEXTEQU <DWORD PTR [esp + 4 + frmPTR]>
|
|
xBit_ TEXTEQU <DWORD PTR [esp + 8 + frmPTR]>
|
|
lDelta_ TEXTEQU <DWORD PTR [esp + 12 + frmPTR]>
|
|
dwControl_ TEXTEQU <DWORD PTR [esp + 16 + frmPTR]>
|
|
pdev_ TEXTEQU <DWORD PTR [esp + 20 + frmPTR]>
|
|
rclBounds_ TEXTEQU <RECTL PTR [esp + 24 + frmPTR]>
|
|
save_ 2
|
|
mov [pdev_], ecx
|
|
|
|
mov ax, [ebp + grCONTROL]
|
|
if DRIVER_5465 AND HW_CLIPPING
|
|
cmp [ecx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR + CLIPEN
|
|
je @F
|
|
REQUIRE 2, ecx
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], CACHE_EXPAND_XPAR + CLIPEN
|
|
mov [ecx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR + CLIPEN
|
|
else
|
|
cmp [ecx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
je @F
|
|
REQUIRE 2, ecx
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], CACHE_EXPAND_XPAR
|
|
mov [ecx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
endif
|
|
@@: ;enable off-screen expansion
|
|
mov [dwControl_], eax
|
|
or eax, SWIZ_CNTL ;enable bit mirroring
|
|
mov edi, [pfo_] ;EDI points to font object
|
|
ASSUME edi:PTR FONTOBJ
|
|
mov [ebp + grCONTROL], ax
|
|
|
|
mov eax, [ebx].rclBounds.left
|
|
;get clipping coordinates
|
|
mov ecx, [ebx].rclBounds.top
|
|
mov edx, [ebx].rclBounds.right
|
|
mov esi, [ebx].rclBounds.bottom
|
|
|
|
mov ebx, [pstro_] ;EBX points to string
|
|
ASSUME ebx:PTR STROBJ
|
|
mov edi, [edi].pvConsumer ;EDI points to font cache
|
|
ASSUME edi:PTR FONTCACHE
|
|
mov [rclBounds_].left, eax ;store clipping coordinates
|
|
mov [rclBounds_].top, ecx
|
|
mov [rclBounds_].right, edx
|
|
mov [rclBounds_].bottom, esi
|
|
|
|
if DRIVER_5465 AND HW_CLIPPING
|
|
;; Set up hardware clipping
|
|
shl ecx, 16 ; Top of clipping rect. in high word
|
|
add eax, ecx ; Packed upper left coordinate
|
|
add eax, [mix_]
|
|
mov ecx, [pdev_]
|
|
ASSUME ecx:PTR PDEV
|
|
REQUIRE 4, ecx
|
|
mov [ebp + grCLIPULE], eax ; Set upper left clipping coordinate
|
|
shl esi, 16 ; Bottom of clipping rect. in high word
|
|
add edx, esi ; Packed lower right coordinate
|
|
add edx, [mix_]
|
|
mov [ebp + grCLIPLOR], edx ; Set lower right clipping coordinate
|
|
endif
|
|
|
|
mov eax, [ebx].ulCharInc ;copy ulCharInc
|
|
cmp [ebx].pgp, 0
|
|
mov [ulCharInc_], eax
|
|
je Enumerate ;there is more than one array
|
|
mov ecx, [ebx].cGlyphs ;get the number of glyphs
|
|
mov ebx, [ebx].pgp ;EBX points to GLYPHPOS
|
|
ASSUME ebx:PTR GLYPHPOS
|
|
mov [bMoreGlyphs_], 0 ;no more glyph arrays
|
|
|
|
MainLoop:
|
|
or ecx, ecx ;any glyphs to draw?
|
|
je SkipLoop ;no
|
|
mov eax, [ebx].ptl.x ;get coordinates of first glyph
|
|
mov edx, [ebx].ptl.y
|
|
GlyphLoop:
|
|
push_ ecx
|
|
mov ecx, [ebx].hg ;get the glyph handle
|
|
cmp [ulCharInc_], 0 ;fixed font?
|
|
jne @F ;no
|
|
mov eax, [ebx].ptl.x ;get coordinates for glyph
|
|
mov edx, [ebx].ptl.y
|
|
@@: shl ecx, 4 ;build index into font cache array
|
|
cmp ecx, MAX_GLYPHS * 16 ;glyph out of range?
|
|
jnl DrawGlyph ;yes, draw it directly
|
|
save_ 3
|
|
mov esi, [edi + ecx*1].aGlyphs.xyPos
|
|
;get off-screen location of glyph
|
|
lea ecx, [edi + ecx*1].aGlyphs
|
|
;load address of cache slot
|
|
ASSUME ecx:PTR GLYPHCACHE
|
|
or esi, esi ;is the glyph already cached?
|
|
jnz @F ;yes
|
|
mov esi, [ebx].pgdf ;cache the glyph
|
|
ASSUME esi:PTR GLYPHDEF
|
|
push eax
|
|
push edx
|
|
push ecx
|
|
INVOKE AllocGlyph,
|
|
edi,
|
|
[esi].pgb,
|
|
ecx
|
|
pop ecx
|
|
pop edx
|
|
pop eax
|
|
mov esi, [ecx].xyPos ;get off-screen location of glyph
|
|
@@: cmp [ecx].cSize, 0 ;is this an empty glyph?
|
|
jl DrawGlyph ;no, in fact it is non-cacheable
|
|
jz Increment ;yes, skip it
|
|
push_ edx
|
|
push_ eax
|
|
push_ edi
|
|
push_ ebx
|
|
add edx, [ecx].ptlOrigin.y ;EDX = top
|
|
mov edi, [ecx].cSize ;get packed width/height
|
|
add eax, [ecx].ptlOrigin.x ;EAX = left
|
|
mov ecx, edi
|
|
ASSUME ecx:NOTHING
|
|
shr edi, 16 ;EDI holds height
|
|
and ecx, 0000FFFFh ;ECX holds width
|
|
add edi, edx ;EDI = bottom
|
|
add ecx, eax ;ECX = right
|
|
|
|
mov ebx, [rclBounds_].left ;clip coordinates
|
|
|
|
ife (DRIVER_5465 AND HW_CLIPPING)
|
|
cmp ecx, [rclBounds_].right ; is the right edge clipped?
|
|
jng @F ;
|
|
mov ecx, [rclBounds_].right ; yes - set new right
|
|
endif
|
|
@@: sub ebx, eax ; is the left edge clipped?
|
|
jg SpecialDraw ; yes
|
|
|
|
sub ecx, eax ; get delta x
|
|
jng SkipGlyph ; right > left? - don't draw it
|
|
mov ebx, [rclBounds_].top
|
|
|
|
ife (DRIVER_5465 AND HW_CLIPPING)
|
|
cmp edi, [rclBounds_].bottom; is the bottom clipped?
|
|
jng @F
|
|
mov edi, [rclBounds_].bottom; yes - set new bottom
|
|
endif
|
|
|
|
@@: sub ebx, edx ; is the top clipped?
|
|
jng @F
|
|
shl ebx, 16 ; top is clipped
|
|
mov edx, [rclBounds_].top ; adjust top
|
|
add esi, ebx ; adjust off-screen top
|
|
@@: sub edi, edx ; bottom > top?
|
|
jng SkipGlyph ; no - skip it
|
|
shl edi, 16 ; pack x/y
|
|
add eax, [mix_] ; add x/y offset
|
|
shl edx, 16 ; top << 16
|
|
or edi, ecx
|
|
add edx, eax ; packed top left corner
|
|
mov ecx, [pdev_]
|
|
ASSUME ecx:PTR PDEV
|
|
REQUIRE 7, ecx
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
;expand glyph from off-screen
|
|
mov [ebp + grOP2_opMRDRAM], esi
|
|
mov [ebp + grBLTEXT_EX], edi
|
|
SkipGlyph:
|
|
pop_ ebx
|
|
pop_ edi
|
|
pop_ eax
|
|
pop_ edx
|
|
|
|
Increment:
|
|
add eax, [ulCharInc_] ;add x-increment
|
|
pop_ ecx
|
|
add ebx, SIZEOF GLYPHPOS ;next glyph
|
|
dec ecx
|
|
jnz GlyphLoop
|
|
SkipLoop:
|
|
cmp [bMoreGlyphs_], 0 ;more arrays of glypos?
|
|
jne Enumerate ;yes
|
|
mov ecx, [dwControl_]
|
|
leave_ 40 ;kill stack frame
|
|
and ecx, NOT SWIZ_CNTL ;disable bit mirroring
|
|
mov eax, 1 ;return TRUE
|
|
mov [ebp + grCONTROL], cx
|
|
pop_ ebx
|
|
pop_ ebp
|
|
pop_ esi
|
|
pop_ edi
|
|
ret 40
|
|
|
|
Enumerate:
|
|
load_ 2
|
|
push_ eax ;create room on stack for return
|
|
push_ eax ; parameters
|
|
mov eax, [pstro_] ;get pointer to STROBJ
|
|
mov ebx, esp ;ebx points to pgp parameter
|
|
lea ecx, [esp + 4] ;ecx points to c parameter
|
|
INVOKE STROBJ_bEnum,
|
|
eax,
|
|
ecx,
|
|
ebx
|
|
pop_ ebx ;load pgp from stack
|
|
pop_ ecx ;load c from stack
|
|
mov [bMoreGlyphs_], eax
|
|
jmp MainLoop
|
|
|
|
;//frido BEGIN 28-Mar-96
|
|
SpecialDraw:
|
|
pop_ ebx
|
|
pop_ edi
|
|
pop_ eax
|
|
pop_ edx
|
|
;//frido END 28-Mar-96
|
|
|
|
;
|
|
; Draw a clipped glyph directly to screen.
|
|
;
|
|
DrawGlyph:
|
|
load_ 3
|
|
mov esi, [ebx].pgdf ;ESI holds pointer to GLYPHDEF
|
|
ASSUME esi:PTR GLYPHDEF
|
|
push_ eax
|
|
push_ edx
|
|
mov esi, [esi].pgb ;ESI holds pointer to GLYPHBITS
|
|
ASSUME esi:PTR GLYPHBITS
|
|
push_ edi
|
|
push_ ebx
|
|
|
|
mov edi, [esi].sizlBitmap._cx
|
|
;EDI = right
|
|
mov ecx, [esi].sizlBitmap._cy
|
|
;ECX = bottom
|
|
add eax, [esi].ptlOrigin.x ;EAX = left
|
|
add edx, [esi].ptlOrigin.y ;EDX = top
|
|
lea ebx, [edi + 7] ;EBX = byte increment to next line
|
|
add edi, eax
|
|
shr ebx, 3
|
|
add ecx, edx
|
|
lea esi, [esi].aj ;ESI holds pointer to bits
|
|
ASSUME esi:NOTHING
|
|
mov [xBit_], 0 ;zero bit offset
|
|
mov [lDelta_], ebx
|
|
|
|
mov ebx, [rclBounds_].left
|
|
cmp edi, [rclBounds_].right ;clip right
|
|
jl @F
|
|
mov edi, [rclBounds_].right
|
|
@@: sub ebx, eax ;clip left
|
|
jng @F
|
|
mov eax, ebx ;store bit offset
|
|
shr ebx, 3
|
|
and eax, 7
|
|
add esi, ebx
|
|
mov [xBit_], eax
|
|
mov eax, [rclBounds_].left
|
|
@@: sub edi, eax ;EDI = width
|
|
jng GoIncrement
|
|
|
|
mov ebx, [rclBounds_].top
|
|
cmp ecx, [rclBounds_].bottom;clip bottom
|
|
jl @F
|
|
mov ecx, [rclBounds_].bottom
|
|
@@: sub ebx, edx ;clip top
|
|
jng @F
|
|
add edx, ebx ;store line offset
|
|
imul ebx, [lDelta_]
|
|
add esi, ebx
|
|
@@: sub ecx, edx ;ECX = height
|
|
jng GoIncrement
|
|
|
|
shl edx, 16 ;pack x,y
|
|
mov ebx, [xBit_]
|
|
shl ecx, 16
|
|
or edx, eax
|
|
or ecx, edi
|
|
add edx, [mix_] ;add x/y offset
|
|
lea edi, [edi + ebx + 7] ;EDI = adjusted width
|
|
IF broken_FIFO
|
|
IDLE
|
|
ENDIF
|
|
mov eax, [pdev_]
|
|
ASSUME eax:PTR PDEV
|
|
REQUIRE 4, eax
|
|
if DRIVER_5465 AND HW_CLIPPING
|
|
cmp [eax].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR + CLIPEN
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], TEXT_EXPAND_XPAR + CLIPEN
|
|
mov [eax].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR + CLIPEN
|
|
@@: ;enable on-screen expansion & clipping
|
|
else
|
|
cmp [eax].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR
|
|
je @F
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], TEXT_EXPAND_XPAR
|
|
mov [eax].shadowDRAWBLTDEF, TEXT_EXPAND_XPAR
|
|
@@: ;enable on-screen expansion
|
|
endif
|
|
IF SWAT7
|
|
mov [ebp + grOP2_opMRDRAM], ebx
|
|
cmp cx, 64 ;bug when doing 64 < width < 128
|
|
jbe SkipBug
|
|
cmp cx, 128
|
|
jae SkipBug
|
|
push_ ecx ;save registers
|
|
push_ edx
|
|
push_ esi
|
|
push_ edi
|
|
mov cx, 64 ;1st passs, 64 pixels
|
|
REQUIRE 5, eax
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
mov [ebp + grBLTEXT_EX], ecx
|
|
shr ecx, 16 ;get height into ECX
|
|
mov edi, [lDelta_] ;get delta
|
|
BugLoop:
|
|
mov eax, [pdev_]
|
|
REQUIRE 2, eax
|
|
mov eax, [esi][0] ;transfer 64 pixels
|
|
mov edx, [esi][4]
|
|
mov [ebp + grHOSTDATA][0], eax
|
|
mov [ebp + grHOSTDATA][4], edx
|
|
or ebx, ebx
|
|
jz @F
|
|
mov edx, [pdev_]
|
|
ASSUME edx:PTR PDEV
|
|
mov eax, [esi][8]
|
|
REQUIRE 1, edx
|
|
mov [ebp + grHOSTDATA][8], eax
|
|
@@: add esi, [lDelta_] ;next glyph line
|
|
dec ecx
|
|
jnz BugLoop
|
|
pop_ edi ;restore registers
|
|
pop_ esi
|
|
sub edi, 64 ;64 pixels less to do
|
|
pop_ edx
|
|
add esi, 64 / 8 ;8 bytes already done
|
|
pop_ ecx
|
|
add edx, 64 ;offset to next 64 pixels
|
|
sub ecx, 64
|
|
SkipBug:
|
|
mov eax, [pdev_]
|
|
ASSUME eax:PTR PDEV
|
|
shr edi, 3
|
|
REQUIRE 5, eax
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
ELSE
|
|
mov eax, [pdev_]
|
|
ASSUME eax:PTR PDEV
|
|
mov [ebp + grOP0_opRDRAM], edx
|
|
REQUIRE 5, eax
|
|
mov [ebp + grOP2_opMRDRAM], ebx
|
|
shr edi, 3
|
|
ENDIF
|
|
mov [ebp + grBLTEXT_EX], ecx
|
|
shr ecx, 16
|
|
mov edx, [lDelta_]
|
|
mov ebx, [pdev_]
|
|
ASSUME ebx:PTR PDEV
|
|
cmp edi, 2
|
|
jb Draw1Byte
|
|
je Draw2Bytes
|
|
cmp edi, 4
|
|
jbe Draw4Bytes
|
|
|
|
DrawLoop:
|
|
push_ edi
|
|
push_ esi
|
|
@@: mov eax, [esi] ;get 4 bytes from glyph
|
|
add esi, 4
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
sub edi, 4 ;4 bytes done
|
|
jg @B ;still more bytes to draw
|
|
pop_ esi
|
|
pop_ edi
|
|
add esi, edx
|
|
dec ecx ;next glyph row
|
|
jnz DrawLoop
|
|
jmp SkipDraw
|
|
|
|
Draw1Byte:
|
|
mov al, [esi] ;get byte from glyph
|
|
add esi, edx
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw it
|
|
dec ecx ;next glyph line
|
|
jnz Draw1Byte
|
|
jmp SkipDraw
|
|
|
|
Draw2Bytes:
|
|
mov ax, [esi] ;get two bytes from glyph
|
|
add esi, edx
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph line
|
|
jnz Draw2Bytes
|
|
jmp SkipDraw
|
|
|
|
Draw4Bytes:
|
|
mov eax, [esi] ;get four bytes from glyph
|
|
add esi, edx
|
|
REQUIRE 1, ebx
|
|
mov [ebp + grHOSTDATA], eax ;draw them
|
|
dec ecx ;next glyph line
|
|
jnz Draw4Bytes
|
|
|
|
SkipDraw:
|
|
if DRIVER_5465 AND HW_CLIPPING
|
|
cmp [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR + CLIPEN
|
|
je @F
|
|
REQUIRE 2, ebx
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], CACHE_EXPAND_XPAR + CLIPEN
|
|
mov [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR + CLIPEN
|
|
@@: ;enable off-screen expansion & clipping
|
|
else
|
|
cmp [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
je @F
|
|
REQUIRE 2, ebx
|
|
mov DWORD PTR [ebp + grDRAWBLTDEF], CACHE_EXPAND_XPAR
|
|
mov [ebx].shadowDRAWBLTDEF, CACHE_EXPAND_XPAR
|
|
@@: ;enable off-screen expansion
|
|
endif
|
|
GoIncrement:
|
|
pop_ ebx
|
|
pop_ edi
|
|
pop_ edx
|
|
pop_ eax
|
|
jmp Increment
|
|
|
|
ClipTextOut ENDP
|
|
|
|
ENDIF ; USE_ASM
|
|
|
|
END
|