You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1930 lines
78 KiB
1930 lines
78 KiB
;---------------------------Module-Header------------------------------;
|
|
; Module Name: fasttext.asm
|
|
;
|
|
; Copyright (c) 1992-1999 Microsoft Corporation
|
|
;-----------------------------------------------------------------------;
|
|
;-----------------------------------------------------------------------;
|
|
; VOID vFastText(GLYPHPOS * pGlyphPos, ULONG ulGlyphCount, PBYTE pTempBuffer,
|
|
; ULONG ulBufDelta, ULONG ulCharInc, DEVSURF * pdsurf,
|
|
; RECTL * prclText, RECTL * prclOpaque, INT iFgColor,
|
|
; INT iBgColor, ULONG fDrawFlags, RECTL * prclClip,
|
|
; RECTL * prclExtra, ULONG iTrgType);
|
|
; pGlyphPos -
|
|
; ulGlyphCount - # of glyphs to draw. Must never be 0.
|
|
; pTempBuffer -
|
|
; ulBufDelta -
|
|
; ulCharInc -
|
|
; pdsurf -
|
|
; prclText -
|
|
; prclOpaque -
|
|
; iFgColor -
|
|
; iBgColor -
|
|
; fDrawFlags -
|
|
; prclClip - array of clipping rectangles
|
|
; prclExtra - array of extra rectanlges to fill in foreground color
|
|
; iTrgType - 0 = VGA; 1 = DFB; 2 = NONE
|
|
;
|
|
; Performs accelerated proportional text drawing.
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; Note: prclClip and prclExtra are null rectangle (yBottom=0) terminated
|
|
; arrays
|
|
;
|
|
; Note: Assumes the text rectangle has a positive height and width. Will
|
|
; not work properly if this is not the case.
|
|
;
|
|
; Note: The opaquing rectangle is assumed to match the text bounding
|
|
; rectangle exactly; prclOpaque is used only to determine whether or
|
|
; not opaquing is required.
|
|
;
|
|
; Note: For maximum performance, we should not bother to draw fully-
|
|
; clipped characters to the temp buffer.
|
|
;
|
|
; Note: We do not handle clipping or bank spanning in the very fast
|
|
; byte-wide-aligned-fixed-pitch console text. This would be an
|
|
; opportunity for somewhat faster console text performance.
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
|
|
comment $
|
|
|
|
The overall approach of this module is to draw the text into a system
|
|
memory buffer, then copy the buffer to the screen a word at a time
|
|
using write mode 3 so that no OUTs and a minimum of display memory reads
|
|
are required.
|
|
|
|
commend $
|
|
|
|
.386
|
|
|
|
ifndef DOS_PLATFORM
|
|
.model small,c
|
|
else
|
|
ifdef STD_CALL
|
|
.model small,c
|
|
else
|
|
.model small,pascal
|
|
endif; STD_CALL
|
|
endif; DOS_PLATFORM
|
|
|
|
assume ds:FLAT,es:FLAT,ss:FLAT
|
|
assume fs:nothing,gs:nothing
|
|
|
|
.xlist
|
|
include stdcall.inc
|
|
include callconv.inc
|
|
include gdii386.inc
|
|
.list
|
|
|
|
;-----------------------------------------------------------------------;
|
|
|
|
.data
|
|
|
|
align 4
|
|
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Tables used to branch into glyph-drawing optimizations.
|
|
;
|
|
; Handles narrow (1-4 bytes wide) glyph drawing, for case where initial byte
|
|
; should be MOVed even if it's not aligned (intended for use in drawing the
|
|
; first glyph in a string). Table format is:
|
|
; Bits 3-2: dest width
|
|
; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
align 4
|
|
MovInitialTableNarrow label dword
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd mov_first_1_wide_rotated_need_last ;nonalign, 1 wide, need last
|
|
dd mov_first_1_wide_unrotated ;aligned, 1 wide
|
|
dd mov_first_1_wide_rotated_no_last ;nonalign, 1 wide, no last
|
|
dd mov_first_1_wide_unrotated ;aligned, 1 wide
|
|
dd mov_first_2_wide_rotated_need_last ;nonalign, 2 wide, need last
|
|
dd mov_first_2_wide_unrotated ;aligned, 2 wide
|
|
dd mov_first_2_wide_rotated_no_last ;nonalign, 2 wide, no last
|
|
dd mov_first_2_wide_unrotated ;aligned, 2 wide
|
|
dd mov_first_3_wide_rotated_need_last ;nonalign, 3 wide, need last
|
|
dd mov_first_3_wide_unrotated ;aligned, 3 wide
|
|
dd mov_first_3_wide_rotated_no_last ;nonalign, 3 wide, no last
|
|
dd mov_first_3_wide_unrotated ;aligned, 3 wide
|
|
dd mov_first_4_wide_rotated_need_last ;nonalign, 4 wide, need last
|
|
dd mov_first_4_wide_unrotated ;aligned, 4 wide
|
|
dd mov_first_4_wide_rotated_no_last ;nonalign, 4 wide, no last
|
|
dd mov_first_4_wide_unrotated ;aligned, 4 wide
|
|
|
|
; Handles narrow (1-4 bytes wide) glyph drawing, for case where initial byte
|
|
; ORed if it's not aligned (intended for use in drawing all but the first glyph
|
|
; in a string). Table format is:
|
|
; Bits 3-2: dest width
|
|
; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
align 4
|
|
OrInitialTableNarrow label dword
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd or_first_1_wide_rotated_need_last ;nonalign, 1 wide, need last
|
|
dd mov_first_1_wide_unrotated ;aligned, 1 wide
|
|
dd or_first_1_wide_rotated_no_last ;nonalign, 1 wide, no last
|
|
dd mov_first_1_wide_unrotated ;aligned, 1 wide
|
|
dd or_first_2_wide_rotated_need_last ;nonalign, 2 wide, need last
|
|
dd mov_first_2_wide_unrotated ;aligned, 2 wide
|
|
dd or_first_2_wide_rotated_no_last ;nonalign, 2 wide, no last
|
|
dd mov_first_2_wide_unrotated ;aligned, 2 wide
|
|
dd or_first_3_wide_rotated_need_last ;nonalign, 3 wide, need last
|
|
dd mov_first_3_wide_unrotated ;aligned, 3 wide
|
|
dd or_first_3_wide_rotated_no_last ;nonalign, 3 wide, no last
|
|
dd mov_first_3_wide_unrotated ;aligned, 3 wide
|
|
dd or_first_4_wide_rotated_need_last ;nonalign, 4 wide, need last
|
|
dd mov_first_4_wide_unrotated ;aligned, 4 wide
|
|
dd or_first_4_wide_rotated_no_last ;nonalign, 4 wide, no last
|
|
dd mov_first_4_wide_unrotated ;aligned, 4 wide
|
|
|
|
; Handles narrow (1-4 bytes wide) glyph drawing, for case where all bytes
|
|
; should be ORed (intended for use in drawing potentially overlapping glyphs).
|
|
; Table format is:
|
|
; Bits 3-2: dest width
|
|
; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
align 4
|
|
OrAllTableNarrow label dword
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd exit_fast_text ;0 wide
|
|
dd or_all_1_wide_rotated_need_last ;nonalign, 1 wide, need last
|
|
dd or_all_1_wide_unrotated ;aligned, 1 wide
|
|
dd or_all_1_wide_rotated_no_last ;nonalign, 1 wide, no last
|
|
dd or_all_1_wide_unrotated ;aligned, 1 wide
|
|
dd or_all_2_wide_rotated_need_last ;nonalign, 2 wide, need last
|
|
dd or_all_2_wide_unrotated ;aligned, 2 wide
|
|
dd or_all_2_wide_rotated_no_last ;nonalign, 2 wide, no last
|
|
dd or_all_2_wide_unrotated ;aligned, 2 wide
|
|
dd or_all_3_wide_rotated_need_last ;nonalign, 3 wide, need last
|
|
dd or_all_3_wide_unrotated ;aligned, 3 wide
|
|
dd or_all_3_wide_rotated_no_last ;nonalign, 3 wide, no last
|
|
dd or_all_3_wide_unrotated ;aligned, 3 wide
|
|
dd or_all_4_wide_rotated_need_last ;nonalign, 4 wide, need last
|
|
dd or_all_4_wide_unrotated ;aligned, 4 wide
|
|
dd or_all_4_wide_rotated_no_last ;nonalign, 4 wide, no last
|
|
dd or_all_4_wide_unrotated ;aligned, 4 wide
|
|
|
|
; Handles arbitrarily wide glyph drawing, for case where initial byte should be
|
|
; MOVed even if it's not aligned (intended for use in drawing the first glyph
|
|
; in a string). Table format is:
|
|
; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
align 4
|
|
MovInitialTableWide label dword
|
|
dd mov_first_N_wide_rotated_need_last ;nonalign, need last
|
|
dd mov_first_N_wide_unrotated ;aligned
|
|
dd mov_first_N_wide_rotated_no_last ;nonalign, no last
|
|
dd mov_first_N_wide_unrotated ;aligned
|
|
|
|
; Handles arbitrarily wide glyph drawing, for case where initial byte should be
|
|
; ORed if it's not aligned (intended for use in drawing all but the first glyph
|
|
; in a string). Table format is:
|
|
; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
align 4
|
|
OrInitialTableWide label dword
|
|
dd or_first_N_wide_rotated_need_last ;nonalign, need last
|
|
dd mov_first_N_wide_unrotated ;aligned
|
|
dd or_first_N_wide_rotated_no_last ;nonalign, no last
|
|
dd mov_first_N_wide_unrotated ;aligned
|
|
|
|
; Handles arbitrarily wide glyph drawing, for case where all bytes should
|
|
; be ORed (intended for use in drawing potentially overlapping glyphs).
|
|
; Table format is:
|
|
; Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
; Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
align 4
|
|
OrAllTableWide label dword
|
|
dd or_all_N_wide_rotated_need_last ;nonalign, need last
|
|
dd or_all_N_wide_unrotated ;aligned
|
|
dd or_all_N_wide_rotated_no_last ;nonalign, no last
|
|
dd or_all_N_wide_unrotated ;aligned
|
|
|
|
; Vectors to entry points for drawing various types of text. '*' means works as
|
|
; is but could be acclerated with a custom scanning loop.
|
|
align 4
|
|
MasterTextTypeTable label dword ;tops aligned overlap fixed pitch
|
|
dd draw_nf_ntb_o_to_temp_start ; N N N *
|
|
dd draw_f_ntb_o_to_temp_start ; N N Y *
|
|
dd draw_nf_ntb_o_to_temp_start ; N Y N
|
|
dd draw_f_ntb_o_to_temp_start ; N Y Y
|
|
dd draw_nf_tb_no_to_temp_start ; Y N N
|
|
dd draw_f_tb_no_to_temp_start ; Y N Y
|
|
dd draw_nf_ntb_o_to_temp_start ; Y Y N *
|
|
dd draw_f_ntb_o_to_temp_start ; Y Y Y *
|
|
dd 0;
|
|
dd 0;
|
|
dd 0;
|
|
dd 0;
|
|
dd 0;
|
|
dd 0;
|
|
dd 0;
|
|
dd 0;
|
|
|
|
|
|
; Masks for clipping for the eight possible left and right edge alignments
|
|
jOpaqueLeftMasks label byte
|
|
db 0ffh,07fh,03fh,01fh,00fh,007h,003h,001h
|
|
|
|
jOpaqueRightMasks label byte
|
|
db 0ffh,080h,0c0h,0e0h,0f0h,0f8h,0fch,0feh
|
|
|
|
dfbfill_jLeftMasks label dword
|
|
db 0ffh,0ffh,0ffh,0ffh
|
|
db 07fh,0ffh,0ffh,0ffh
|
|
db 03fh,0ffh,0ffh,0ffh
|
|
db 01fh,0ffh,0ffh,0ffh
|
|
db 00fh,0ffh,0ffh,0ffh
|
|
db 007h,0ffh,0ffh,0ffh
|
|
db 003h,0ffh,0ffh,0ffh
|
|
db 001h,0ffh,0ffh,0ffh
|
|
db 000h,0ffh,0ffh,0ffh
|
|
db 000h,07fh,0ffh,0ffh
|
|
db 000h,03fh,0ffh,0ffh
|
|
db 000h,01fh,0ffh,0ffh
|
|
db 000h,00fh,0ffh,0ffh
|
|
db 000h,007h,0ffh,0ffh
|
|
db 000h,003h,0ffh,0ffh
|
|
db 000h,001h,0ffh,0ffh
|
|
db 000h,000h,0ffh,0ffh
|
|
db 000h,000h,07fh,0ffh
|
|
db 000h,000h,03fh,0ffh
|
|
db 000h,000h,01fh,0ffh
|
|
db 000h,000h,00fh,0ffh
|
|
db 000h,000h,007h,0ffh
|
|
db 000h,000h,003h,0ffh
|
|
db 000h,000h,001h,0ffh
|
|
db 000h,000h,000h,0ffh
|
|
db 000h,000h,000h,07fh
|
|
db 000h,000h,000h,03fh
|
|
db 000h,000h,000h,01fh
|
|
db 000h,000h,000h,00fh
|
|
db 000h,000h,000h,007h
|
|
db 000h,000h,000h,003h
|
|
db 000h,000h,000h,001h
|
|
|
|
dfbfill_jRightMasks label dword
|
|
db 0ffh,0ffh,0ffh,0ffh
|
|
db 080h,000h,000h,000h
|
|
db 0c0h,000h,000h,000h
|
|
db 0e0h,000h,000h,000h
|
|
db 0f0h,000h,000h,000h
|
|
db 0f8h,000h,000h,000h
|
|
db 0fch,000h,000h,000h
|
|
db 0feh,000h,000h,000h
|
|
db 0ffh,000h,000h,000h
|
|
db 0ffh,080h,000h,000h
|
|
db 0ffh,0c0h,000h,000h
|
|
db 0ffh,0e0h,000h,000h
|
|
db 0ffh,0f0h,000h,000h
|
|
db 0ffh,0f8h,000h,000h
|
|
db 0ffh,0fch,000h,000h
|
|
db 0ffh,0feh,000h,000h
|
|
db 0ffh,0ffh,000h,000h
|
|
db 0ffh,0ffh,080h,000h
|
|
db 0ffh,0ffh,0c0h,000h
|
|
db 0ffh,0ffh,0e0h,000h
|
|
db 0ffh,0ffh,0f0h,000h
|
|
db 0ffh,0ffh,0f8h,000h
|
|
db 0ffh,0ffh,0fch,000h
|
|
db 0ffh,0ffh,0feh,000h
|
|
db 0ffh,0ffh,0ffh,000h
|
|
db 0ffh,0ffh,0ffh,080h
|
|
db 0ffh,0ffh,0ffh,0c0h
|
|
db 0ffh,0ffh,0ffh,0e0h
|
|
db 0ffh,0ffh,0ffh,0f0h
|
|
db 0ffh,0ffh,0ffh,0f8h
|
|
db 0ffh,0ffh,0ffh,0fch
|
|
db 0ffh,0ffh,0ffh,0feh
|
|
|
|
dfbfill_pfnScanHandlers label dword
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
|
|
|
|
;-----------------------------------------------------------------------;
|
|
|
|
.code
|
|
|
|
|
|
_TEXT$01 SEGMENT DWORD USE32 PUBLIC 'CODE'
|
|
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
;-----------------------------------------------------------------------;
|
|
|
|
|
|
extrn draw_gray_nf_ntb_o_to_temp_start@28:NEAR
|
|
extrn draw_gray_f_ntb_o_to_temp_start@28:NEAR
|
|
|
|
cProc vFastText,52,<\
|
|
uses esi edi ebx,\
|
|
pGlyphPos:ptr,\
|
|
ulGlyphCount:dword,\
|
|
pTempBuffer:ptr,\
|
|
ulBufDelta:dword,\
|
|
ulCharInc:dword,\
|
|
pdsurf:ptr,\
|
|
prclText:ptr,\
|
|
prclOpaque:ptr,\
|
|
iFgColor:dword,\
|
|
iBgColor:dword,\
|
|
fDrawFlags:dword,\
|
|
prclClip:dword,\
|
|
prclExtra:dword>
|
|
|
|
local ulGlyDelta:dword ;width per scan of source glyph, in bytes
|
|
local ulWidthInBytes:dword ;width of glyph, in bytes
|
|
local ulTmpWidthInBytes:dword ;working byte-width count
|
|
local ulGlyphX:dword ;for fixed-pitch text, maintains the current
|
|
; glyph's left-edge X coordinate
|
|
local pGlyphLoop:dword ;pointer to glyph-processing loop
|
|
local ulTempLeft:dword ;X coordinate on screen of left edge of temp
|
|
; buffer
|
|
local ulTempTop:dword ;Y coordinate on screen of top edge of temp
|
|
; buffer
|
|
local ulLoopCount:dword ;general loop count storage
|
|
local ulTmpSrcDelta:dword ;distance from end of one buffer text scan to
|
|
; start of next
|
|
local ulTmpDstDelta:dword ;distance from end of one screen text scan to
|
|
; start of next
|
|
local ulTopScan:dword ;top scan of dest text rect in current bank
|
|
local ulBottomScan:dword ;bottom scan of dest text rect
|
|
local ulNumScans:dword ;# of scans to draw
|
|
local ulScreenDelta:dword ;scan-to-scan offset in screen
|
|
local ulTextWidthInBytes:dword ;# of bytes across spanned by text
|
|
local pScreen:dword ;pointer to first screen byte to which to draw
|
|
local pfnEdgeVector:dword ;pointer to routine to draw any needed edges
|
|
local pfnFirstOpaqVector:dword ;pointer to initial drawing routine
|
|
; called for opaque (either whole
|
|
; bytes, or edge(s) if no whole bytes)
|
|
local ulWholeWidthInWords:dword ;# of whole words to copy
|
|
local ulWholeWidthInWordsMinus1:dword ;# of whole words to copy, -1
|
|
local ulOddByte:dword ;1 if odd byte in whole word copy
|
|
local ulTextLeft:dword ;left edge of leftmost glyph
|
|
local ulLeftMask:dword ;for opaque text, left edge mask for string
|
|
local ulRightMask:dword ;for opaque text, right edge mask for string
|
|
local ulScans:dword ;# of scans to draw
|
|
local ulYOrigin:dword ;Y origin of text in string (all glyphs are at
|
|
; the same Y origin)
|
|
local rclClippedBounds[16]:byte ;clipped destination rectangle;
|
|
; defined as "byte" due to assembler
|
|
; limitations
|
|
|
|
local ulRectLeft:dword
|
|
local ulRectRight:dword
|
|
local pfnDrawScans:dword ;ptr to correct scan drawing function
|
|
local pTempBufferSaved:dword
|
|
local ulEdgeFlags:dword
|
|
local ulBytesPerDstPlane:dword
|
|
local ulLeftOffset:dword
|
|
local pSrc:dword
|
|
local pDst:dword
|
|
local ulPlaneBit:dword
|
|
|
|
TRAILING_PARTIAL equ 01h ;partial trailing dword should be copied
|
|
LEADING_PARTIAL equ 02h ;partial leading dword should be copied
|
|
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; For the moment, handle grayed text using the most general routine
|
|
; This means that we will be handing it back to the most general of
|
|
; of the C routines, namely
|
|
;
|
|
; VOID
|
|
; draw_gray_nf_ntb_o_to_temp_start(
|
|
; PGLYPHPOS pGlyphPos
|
|
; ULONG cGlyph
|
|
; PUCHAR pjTempBuffer
|
|
; ULONG BufferOffset
|
|
; ULONG ulBufferWidthInBytes
|
|
; ULONG ulCharInc
|
|
; ULONG ulTempTop
|
|
; )
|
|
;
|
|
; or for fixed pitch fonts
|
|
;
|
|
; VOID
|
|
; draw_gray_f_ntb_o_to_temp_start(
|
|
; PGLYPHPOS pGlyphPos
|
|
; ULONG cGlyph
|
|
; PUCHAR pjTempBuffer
|
|
; ULONG BufferOffset
|
|
; ULONG ulBufferWidthInBytes
|
|
; ULONG ulCharInc
|
|
; ULONG ulTempTop
|
|
; )
|
|
;
|
|
; Most of these parameters are in the arguments passed to vFastText.
|
|
; However, there are a couple that we must reconstruct. The first
|
|
; parameter to be pushed is ulTempTop. I look into the calling
|
|
; routine (vExpandAndCopyText) and find
|
|
;
|
|
; ulTempTop = prclText->top
|
|
; BufferOffset = 8 * floor(prclText->left/8)
|
|
;
|
|
; The factor of 8 is equal to the number of pixels contained in
|
|
; a DWORD. For monochrome text, this number would become 32
|
|
;
|
|
; The third argument to vFastText is pjTempBuffer which is equal to
|
|
;
|
|
; pjTempBuffer = pTempBuffer - ((prclText->left >> 3) & 3)
|
|
;
|
|
; (to draw_gray..) (input to vFastText)
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
|
|
;gray_text_test:
|
|
mov edx,fDrawFlags ; Is this call for grayed text?
|
|
test edx,8 ; test for ETO_GRAY in fDrawFlags
|
|
jz monochrome_text ; if not go to monochrome code
|
|
;gray_text:
|
|
mov ebx,prclText ; ebx = useful pointer to text rect
|
|
push [ebx].yTop ; ulTempTop: 7'th argument
|
|
push ulCharInc ; ulCharInc: 6'th argument
|
|
push ulBufDelta ; dpDst: 5'th argument
|
|
mov eax,[ebx].xLeft ; eax = prclText->left
|
|
mov ecx,eax ; ecx = prclText->left
|
|
and ecx,not 7 ; ecx = 8 * (prclText->left / 8)
|
|
push ecx ; BufferOffset: 4'th argument
|
|
sar eax,3 ; This is the part where we
|
|
and eax,3 ; correct pjTempBuffer by subtracting
|
|
neg eax ; off an additional factor (see above)
|
|
add eax,pTempBuffer ; eax = pjTempBuffer[draw_gray..]
|
|
push eax ; pjTempBuffer: 3'rd argument
|
|
push ulGlyphCount ; cGlyph: 2'nd argument
|
|
push pGlyphPos ; pGlyphPos: 1'st argument
|
|
mov eax,draw_gray_f_ntb_o_to_temp_start@28
|
|
test edx,1 ; fixed pitch ?
|
|
jnz @f ; yes, eax is good, jump
|
|
mov eax,draw_gray_nf_ntb_o_to_temp_start@28
|
|
@@:
|
|
call eax
|
|
jmp exit_fast_text
|
|
monochrome_text:
|
|
|
|
cld
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Draws either a fixed or a non-fixed-pitch string to the temporary
|
|
; buffer. Assumes this is a horizontal string, so the origins of all glyphs
|
|
; are at the same Y coordinate. Draws leftmost glyph entirely with MOVs,
|
|
; even if it's not aligned, in order to ensure that the leftmost byte
|
|
; gets cleared when we're working with butted characters. For other
|
|
; non-aligned glyphs, leftmost byte is ORed, other bytes are MOVed.
|
|
;
|
|
; Input:
|
|
; pGlyphPos = pointer to array of GLYPHPOS structures to draw
|
|
; ulGlyphCount = # of glyphs to draw
|
|
; ulTempLeft = X coordinate on dest of left edge of temp buffer pointed
|
|
; to by pTempBuffer
|
|
; pTempBuffer = pointer to first byte (upper left corner) of
|
|
; temp buffer into which we're drawing. This should be
|
|
; dword-aligned with the destination
|
|
; ulBufDelta = destination scan-to-scan offset
|
|
; ulCharInc = offset from one glyph to next (fixed-pitch only)
|
|
; fDrawFlags = indicate the type of text to be drawn
|
|
; Temp buffer zeroed if text doesn't cover every single pixel
|
|
;
|
|
; Fixed-pitch means equal spacing between glyph positions, not that all
|
|
; glyphs butt together or equal spacing between upper left corners.
|
|
;-----------------------------------------------------------------------;
|
|
|
|
mov ebx,prclText
|
|
sub eax,eax
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Handle all cases other than 8-wide byte-aligned.
|
|
;-----------------------------------------------------------------------;
|
|
|
|
general_handler:
|
|
mov esi,pdsurf
|
|
mov eax,[ebx].yTop
|
|
mov ulTempTop,eax ;Y screen coordinate of top edge of temp buf
|
|
mov eax,[ebx].xLeft
|
|
and eax,not 7
|
|
mov ulTempLeft,eax ;X screen coordinate of left edge of temp buf
|
|
mov eax,[esi].dsurf_lNextScan
|
|
mov ulScreenDelta,eax
|
|
|
|
mov eax,fDrawFlags
|
|
|
|
jmp MasterTextTypeTable[eax*4]
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Entry point for fixed-pitch | tops and bottoms aligned | no overlap.
|
|
; Sets up to draw first glyph.
|
|
;-----------------------------------------------------------------------;
|
|
draw_f_tb_no_to_temp_start::
|
|
mov ebx,pGlyphPos ;point to the first glyph to draw
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
|
|
mov edi,[ebx].gp_x ;dest X coordinate
|
|
sub edi,ulTempLeft ;adjust relative to the left of the
|
|
; temp buffer (we assume the text is
|
|
; right at the top of the text rect
|
|
; and hence the buffer)
|
|
mov ulGlyphX,edi ;remember where this glyph started
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
mov pGlyphLoop,offset draw_f_tb_no_to_temp_loop
|
|
;draw additional characters with this
|
|
; loop
|
|
jmp short draw_to_temp_start_entry
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Entry point for non-fixed-pitch | tops and bottoms aligned | no overlap.
|
|
; Sets up to draw first glyph.
|
|
;-----------------------------------------------------------------------;
|
|
draw_nf_tb_no_to_temp_start::
|
|
mov ebx,pGlyphPos ;point to the first glyph to draw
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
|
|
mov edi,[ebx].gp_x ;dest X coordinate
|
|
sub edi,ulTempLeft ;adjust relative to the left of the
|
|
; temp buffer
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
mov pGlyphLoop,offset draw_nf_tb_no_to_temp_loop
|
|
;draw additional characters with this
|
|
; loop
|
|
draw_to_temp_start_entry::
|
|
add edi,[esi].gb_x ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mov ecx,edi
|
|
shr edi,3 ;byte offset of first column of glyph
|
|
; offset of upper left of glyph in temp
|
|
; buffer
|
|
add edi,pTempBuffer ;initial dest byte in temp buffer
|
|
|
|
and ecx,111b ;bit alignment of upper left in temp
|
|
|
|
;calculate scan-to-scan glyph width
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
|
|
lea eax,[ebx+ecx+7]
|
|
shr eax,3 ;# of dest bytes per scan
|
|
|
|
add ebx,7
|
|
shr ebx,3 ;# of source bytes per scan
|
|
|
|
mov edx,ulBufDelta ;width of destination buffer in bytes
|
|
|
|
cmp eax,4 ;do we have special case code for this
|
|
; dest width?
|
|
ja short @F ;no, handle as general case
|
|
;yes, handle as special case
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp MovInitialTableNarrow[eax*4]
|
|
;branch to draw the first glyph; never
|
|
; need to OR first glyph, because
|
|
; there's nothing there yet
|
|
|
|
@@: ;too wide to special case
|
|
mov ulWidthInBytes,eax ;# of bytes across dest
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
mov eax,0
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
add ebx,7
|
|
shr ebx,3 ;glyph width in bytes
|
|
mov ulGlyDelta,ebx
|
|
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp MovInitialTableWide[eax*4]
|
|
;branch to draw the first glyph; never
|
|
; need to OR first glyph, because
|
|
; there's nothing there yet
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Entry point for fixed-pitch | tops and bottoms not aligned | overlap.
|
|
; Sets up to draw first glyph.
|
|
;-----------------------------------------------------------------------;
|
|
draw_f_ntb_o_to_temp_start::
|
|
mov ebx,pGlyphPos ;point to the first glyph to draw
|
|
mov pGlyphLoop,offset draw_f_ntb_o_to_temp_loop
|
|
;draw additional characters with this
|
|
; loop
|
|
mov edi,[ebx].gp_x ;dest X coordinate
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
sub edi,ulTempLeft ;adjust relative to the left of the
|
|
; temp buffer
|
|
mov ulGlyphX,edi ;remember where this glyph started
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
add edi,[esi].gb_x ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mov ecx,edi
|
|
shr edi,3 ;byte offset of first column of glyph
|
|
; offset of upper left of glyph in temp
|
|
; buffer
|
|
jmp short draw_to_temp_start_entry2
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Entry point for non-fixed-pitch | tops and bottoms not aligned | overlap.
|
|
; Sets up to draw first glyph.
|
|
;-----------------------------------------------------------------------;
|
|
draw_nf_ntb_o_to_temp_start::
|
|
mov ebx,pGlyphPos ;point to the first glyph to draw
|
|
mov pGlyphLoop,offset draw_nf_ntb_o_to_temp_loop
|
|
;draw additional characters with this
|
|
; loop
|
|
mov edi,[ebx].gp_x ;dest X coordinate
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
sub edi,ulTempLeft ;adjust relative to the left of the
|
|
; temp buffer
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
add edi,[esi].gb_x ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mov ecx,edi
|
|
shr edi,3 ;byte offset of first column of glyph
|
|
; offset of upper left of glyph in temp
|
|
; buffer
|
|
draw_to_temp_start_entry2::
|
|
mov eax,[ebx].gp_y ;dest origin Y coordinate
|
|
sub eax,ulTempTop ;coord of glyph origin in temp buffer
|
|
mov ulYOrigin,eax ;remember the Y origin of all glyphs
|
|
; (necessary because glyph positions
|
|
; after first aren't set for fixed-
|
|
; pitch strings)
|
|
add eax,[esi].gb_y ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mul ulBufDelta ;offset in buffer of top glyph scan
|
|
add eax,pTempBuffer ;initial dest byte
|
|
add edi,eax
|
|
|
|
and ecx,111b ;bit alignment of upper left in temp
|
|
|
|
;calculate scan-to-scan glyph width
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
|
|
lea eax,[ebx+ecx+7]
|
|
shr eax,3 ;# of dest bytes per scan
|
|
|
|
add ebx,7
|
|
shr ebx,3 ;# of source bytes per scan
|
|
|
|
mov edx,ulBufDelta ;width of destination buffer in bytes
|
|
|
|
cmp eax,4 ;do we have special case code for this
|
|
; dest width?
|
|
ja short @F ;no, handle as general case
|
|
;yes, handle as special case
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp OrAllTableNarrow[eax*4] ;branch to draw the first glyph; OR all
|
|
; glyphs, because text may overlap
|
|
|
|
@@: ;too wide to special case
|
|
mov ulWidthInBytes,eax ;# of bytes across dest
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
mov eax,0
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
add ebx,7
|
|
shr ebx,3 ;glyph width in bytes
|
|
mov ulGlyDelta,ebx
|
|
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp OrAllTableWide[eax*4] ;branch to draw the first glyph; OR all
|
|
; glyphs, because text may overlap
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Loop to draw all fixed-pitch | tops and bottoms aligned | no overlap
|
|
; glyphs after first.
|
|
;-----------------------------------------------------------------------;
|
|
draw_f_tb_no_to_temp_loop::
|
|
dec ulGlyphCount ;any more glyphs to draw?
|
|
jz glyphs_are_done ;no, done
|
|
mov ebx,pGlyphPos
|
|
add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one
|
|
mov pGlyphPos,ebx ; we're going to draw this time)
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
|
|
mov edi,ulGlyphX ;last glyph's dest X start in temp buf
|
|
add edi,ulCharInc ;this glyph's dest X start in temp buf
|
|
mov ulGlyphX,edi ;remember for next glyph
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
jmp short draw_to_temp_loop_entry
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Loop to draw all non-fixed-pitch | tops and bottoms aligned | no overlap
|
|
; glyphs after first.
|
|
;-----------------------------------------------------------------------;
|
|
draw_nf_tb_no_to_temp_loop::
|
|
dec ulGlyphCount ;any more glyphs to draw?
|
|
jz glyphs_are_done ;no, done
|
|
mov ebx,pGlyphPos
|
|
add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one we're
|
|
mov pGlyphPos,ebx ; going to draw this time)
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
mov edi,[ebx].gp_x ;dest X coordinate
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
sub edi,ulTempLeft ;adjust relative to the left edge of
|
|
; the temp buffer
|
|
|
|
draw_to_temp_loop_entry::
|
|
add edi,[esi].gb_x ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mov ecx,edi ;pixel X coordinate in temp buffer
|
|
shr edi,3 ;byte offset of first column = dest
|
|
; offset of upper left of glyph in temp
|
|
; buffer
|
|
add edi,pTempBuffer ;initial dest byte
|
|
|
|
and ecx,111b ;bit alignment of upper left in temp
|
|
|
|
;calculate scan-to-scan glyph width
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
|
|
lea eax,[ebx+ecx+7]
|
|
shr eax,3 ;# of dest bytes to copy to per scan
|
|
|
|
add ebx,7
|
|
shr ebx,3 ;# of source bytes to copy from per
|
|
; scan
|
|
mov edx,ulBufDelta ;width of destination buffer in bytes
|
|
|
|
cmp eax,4 ;do we have special case code for this
|
|
; dest width?
|
|
ja short @F ;no, handle as general case
|
|
;yes, handle as special case
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp OrInitialTableNarrow[eax*4] ;branch to draw the first glyph;
|
|
; need to OR the 1st byte if
|
|
; non-aligned to avoid overwriting
|
|
; what's already there
|
|
@@: ;too wide to special case
|
|
mov ulWidthInBytes,eax ;# of bytes across dest
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
mov eax,0
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
add ebx,7
|
|
shr ebx,3 ;glyph width in bytes
|
|
mov ulGlyDelta,ebx
|
|
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp OrInitialTableWide[eax*4] ;branch to draw the next glyph;
|
|
; need to OR the 1st byte if
|
|
; non-aligned to avoid overwriting
|
|
; what's already there
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Loop to draw all fixed-pitch | tops and bottoms not aligned | overlap
|
|
; glyphs after first.
|
|
;-----------------------------------------------------------------------;
|
|
draw_f_ntb_o_to_temp_loop::
|
|
dec ulGlyphCount ;any more glyphs to draw?
|
|
jz glyphs_are_done ;no, done
|
|
mov ebx,pGlyphPos
|
|
add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one we're
|
|
mov pGlyphPos,ebx ; going to draw this time)
|
|
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
mov edi,ulGlyphX ;last glyph's dest X start in temp buf
|
|
add edi,ulCharInc ;this glyph's dest X start in temp buf
|
|
mov ulGlyphX,edi ;remember for next glyph
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
|
|
mov eax,ulYOrigin ;dest Y coordinate
|
|
jmp short draw_to_temp_loop_entry2
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Loop to draw all non-fixed-pitch | tops and bottoms not aligned | overlap
|
|
; glyphs after first.
|
|
;-----------------------------------------------------------------------;
|
|
draw_nf_ntb_o_to_temp_loop::
|
|
dec ulGlyphCount ;any more glyphs to draw?
|
|
jz glyphs_are_done ;no, done
|
|
mov ebx,pGlyphPos
|
|
add ebx,SIZE_GLYPHPOS ;point to the next glyph (the one we're
|
|
mov pGlyphPos,ebx ; going to draw this time)
|
|
|
|
mov esi,[ebx].gp_pgdf ;point to glyph def
|
|
mov edi,[ebx].gp_x ;dest X coordinate
|
|
mov esi,[esi].gdf_pgb ;point to glyph bits
|
|
sub edi,ulTempLeft ;adjust relative to the left edge of
|
|
; the temp buffer
|
|
mov eax,[ebx].gp_y ;dest origin Y coordinate
|
|
sub eax,ulTempTop ;coord of glyph origin in temp buffer
|
|
draw_to_temp_loop_entry2::
|
|
add edi,[esi].gb_x ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mov ecx,edi ;pixel X coordinate in temp buffer
|
|
shr edi,3 ;byte offset of first column = dest
|
|
; offset of upper left of glyph in temp
|
|
; buffer
|
|
|
|
add eax,[esi].gb_y ;adjust to position of upper left glyph
|
|
; corner in dest
|
|
mul ulBufDelta ;offset in buffer of top glyph scan
|
|
add eax,pTempBuffer ;initial dest byte
|
|
add edi,eax
|
|
|
|
and ecx,111b ;bit alignment of upper left in temp
|
|
|
|
;calculate scan-to-scan glyph width
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
|
|
lea eax,[ebx+ecx+7]
|
|
shr eax,3 ;# of dest bytes to copy to per scan
|
|
|
|
add ebx,7
|
|
shr ebx,3 ;# of source bytes to copy from per
|
|
; scan
|
|
mov edx,ulBufDelta ;width of destination buffer in bytes
|
|
|
|
cmp eax,4 ;do we have special case code for this
|
|
; dest width?
|
|
ja short @F ;no, handle as general case
|
|
;yes, handle as special case
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp OrAllTableNarrow[eax*4] ;branch to draw the next glyph
|
|
|
|
@@: ;too wide to special case
|
|
mov ulWidthInBytes,eax ;# of bytes across dest
|
|
cmp ebx,eax ;carry if more dest than source bytes
|
|
; (last source byte not needed)
|
|
mov eax,0
|
|
rcl eax,1 ;factor last source byte status in
|
|
cmp cl,1 ;carry if aligned
|
|
rcl eax,1 ;factor in alignment (aligned or not)
|
|
|
|
mov ebx,[esi].gb_cx ;glyph width in pixels
|
|
add ebx,7
|
|
shr ebx,3 ;glyph width in bytes
|
|
mov ulGlyDelta,ebx
|
|
|
|
mov ebx,[esi].gb_cy ;# of scans in glyph
|
|
add esi,gb_aj ;point to the first glyph byte
|
|
|
|
jmp OrAllTableWide[eax*4] ;branch to draw the next glyph
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Routines to draw all scans of a single glyph into the temp buffer,
|
|
; optimized for the following cases:
|
|
;
|
|
; 1 to 4 byte-wide destination rectangles for each of:
|
|
; No rotation needed
|
|
; Rotation needed, same # of source as dest bytes needed
|
|
; Rotation needed, one less source than dest bytes needed
|
|
;
|
|
; Additionally, the three cases are handled for 5 and wider cases by a
|
|
; general routine for each case.
|
|
;
|
|
; If rotation is needed, there are three sorts of routines:
|
|
;
|
|
; 1) The leftmost byte is MOVed, to initialize the byte. Succeeding bytes are
|
|
; MOVed. This is generally used for the leftmost glyph of a string.
|
|
; 2) The leftmost byte is ORed into the existing byte. Succeeding bytes are
|
|
; MOVed. This is generally used after the leftmost glyph, because this may
|
|
; not be the first data written to that byte.
|
|
; 3) All bytes are ORed. This is for drawing when characters might overlap.
|
|
;
|
|
; If rotation is not needed, there are two sorts of routines:
|
|
;
|
|
; 1) The leftmost byte is MOVed, to initialize the byte. Succeeding bytes are
|
|
; MOVed. This is generally used for the leftmost glyph of a string.
|
|
; 2) All bytes are ORed. This is for drawing when characters might overlap.
|
|
;
|
|
; On entry:
|
|
; EBX = # of scans to copy
|
|
; CL = right rotation
|
|
; EDX = ulBufDelta = width per scan of destination buffer, in bytes
|
|
; ESI = pointer to first glyph byte
|
|
; EDI = pointer to first dest buffer byte
|
|
; DF = cleared
|
|
; ulGlyDelta = width per scan of source glyph, in bytes (wide case only)
|
|
; ulWidthInBytes = width of glyph, in bytes (required only for 5 and
|
|
; wider cases)
|
|
;
|
|
; On exit:
|
|
; Any or all of EAX, EBX, ECX, EDX, ESI, and EDI may be trashed.
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 1 byte wide dest, rotated.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_1_wide_rotated_need_last::
|
|
or_all_1_wide_rotated_no_last::
|
|
or_first_1_wide_rotated_need_last::
|
|
or_first_1_wide_rotated_no_last::
|
|
or_first_1_wide_rotated_loop::
|
|
mov ch,[esi]
|
|
inc esi
|
|
shr ch,cl
|
|
or [edi],ch
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_first_1_wide_rotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 1 byte wide dest, rotated.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_1_wide_rotated_need_last::
|
|
mov_first_1_wide_rotated_no_last::
|
|
mov_first_1_wide_rotated_loop::
|
|
mov ch,[esi]
|
|
inc esi
|
|
shr ch,cl
|
|
mov [edi],ch
|
|
add edi,edx
|
|
dec ebx
|
|
jnz mov_first_1_wide_rotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 1 byte wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_1_wide_unrotated::
|
|
mov_first_1_wide_unrotated_loop::
|
|
mov al,[esi]
|
|
inc esi
|
|
mov [edi],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz mov_first_1_wide_unrotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 1 byte wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_1_wide_unrotated::
|
|
or_all_1_wide_unrotated_loop::
|
|
mov al,[esi]
|
|
inc esi
|
|
or [edi],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_all_1_wide_unrotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 2 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_2_wide_rotated_need_last::
|
|
or_first_2_wide_rotated_need_loop::
|
|
mov ax,[esi]
|
|
add esi,2
|
|
ror ax,cl
|
|
or [edi],al
|
|
mov [edi+1],ah
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_first_2_wide_rotated_need_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 2 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_2_wide_rotated_need_last::
|
|
or_all_2_wide_rotated_need_loop::
|
|
mov ax,[esi]
|
|
add esi,2
|
|
ror ax,cl
|
|
or [edi],ax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_all_2_wide_rotated_need_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 2 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_2_wide_rotated_need_last::
|
|
mov_first_2_wide_rotated_need_loop::
|
|
mov ax,[esi]
|
|
add esi,2
|
|
ror ax,cl
|
|
mov [edi],ax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz mov_first_2_wide_rotated_need_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 2 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_2_wide_rotated_no_last::
|
|
or_first_2_wide_rotated_loop::
|
|
sub eax,eax
|
|
mov ah,[esi]
|
|
inc esi
|
|
shr eax,cl
|
|
or [edi],ah
|
|
mov [edi+1],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_first_2_wide_rotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 2 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_2_wide_rotated_no_last::
|
|
or_all_2_wide_rotated_loop::
|
|
sub eax,eax
|
|
mov al,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
or [edi],ax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_all_2_wide_rotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 2 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_2_wide_rotated_no_last::
|
|
mov_first_2_wide_rotated_loop::
|
|
sub eax,eax
|
|
mov al,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
mov [edi],ax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz mov_first_2_wide_rotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 2 bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_2_wide_unrotated::
|
|
mov_first_2_wide_unrotated_loop::
|
|
mov ax,[esi]
|
|
add esi,2
|
|
mov [edi],ax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz mov_first_2_wide_unrotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 2 bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_2_wide_unrotated::
|
|
or_all_2_wide_unrotated_loop::
|
|
mov ax,[esi]
|
|
add esi,2
|
|
or [edi],ax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz or_all_2_wide_unrotated_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 3 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_3_wide_rotated_need_last::
|
|
@@:
|
|
mov al,[esi]
|
|
shr al,cl
|
|
or [edi],al
|
|
mov ax,[esi]
|
|
ror ax,cl
|
|
mov [edi+1],ah
|
|
mov ax,[esi+1]
|
|
add esi,3
|
|
ror ax,cl
|
|
mov [edi+2],ah
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 3 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_3_wide_rotated_need_last::
|
|
@@:
|
|
mov al,[esi]
|
|
shr al,cl
|
|
or [edi],al
|
|
mov ax,[esi]
|
|
ror ax,cl
|
|
or [edi+1],ah
|
|
mov ax,[esi+1]
|
|
add esi,3
|
|
ror ax,cl
|
|
or [edi+2],ah
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 3 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_3_wide_rotated_need_last::
|
|
@@:
|
|
mov al,[esi]
|
|
shr al,cl
|
|
mov [edi],al
|
|
mov ax,[esi]
|
|
ror ax,cl
|
|
mov [edi+1],ah
|
|
mov ax,[esi+1]
|
|
add esi,3
|
|
ror ax,cl
|
|
mov [edi+2],ah
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 3 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_3_wide_rotated_no_last::
|
|
neg cl
|
|
and cl,111b ;convert from right shift to left shift
|
|
@@:
|
|
sub eax,eax
|
|
mov ax,[esi]
|
|
add esi,2
|
|
xchg ah,al
|
|
shl eax,cl
|
|
mov [edi+1],ah
|
|
mov [edi+2],al
|
|
shr eax,16
|
|
or [edi],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 3 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_3_wide_rotated_no_last::
|
|
neg cl
|
|
and cl,111b ;convert from right shift to left shift
|
|
@@:
|
|
sub eax,eax
|
|
mov ax,[esi]
|
|
add esi,2
|
|
xchg ah,al
|
|
shl eax,cl
|
|
xchg ah,al
|
|
or [edi+1],ax
|
|
shr eax,16
|
|
or [edi],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 3 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_3_wide_rotated_no_last::
|
|
neg cl
|
|
and cl,111b ;convert from right shift to left shift
|
|
@@:
|
|
sub eax,eax
|
|
mov ax,[esi]
|
|
add esi,2
|
|
xchg ah,al
|
|
shl eax,cl
|
|
mov [edi+1],ah
|
|
mov [edi+2],al
|
|
shr eax,16
|
|
mov [edi],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 3 bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_3_wide_unrotated::
|
|
@@:
|
|
mov ax,[esi]
|
|
mov [edi],ax
|
|
mov al,[esi+2]
|
|
add esi,3
|
|
mov [edi+2],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 3 bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_3_wide_unrotated::
|
|
@@:
|
|
mov ax,[esi]
|
|
or [edi],ax
|
|
mov al,[esi+2]
|
|
add esi,3
|
|
or [edi+2],al
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 4 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_4_wide_rotated_need_last::
|
|
@@:
|
|
mov eax,[esi]
|
|
add esi,4
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg ah,al
|
|
shr eax,cl
|
|
xchg ah,al
|
|
mov [edi+2],ax
|
|
shr eax,16
|
|
mov [edi+1],al
|
|
or [edi],ah
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 4 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_4_wide_rotated_need_last::
|
|
@@:
|
|
mov eax,[esi]
|
|
add esi,4
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg ah,al
|
|
shr eax,cl
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg al,ah
|
|
or [edi],eax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 4 bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_4_wide_rotated_need_last::
|
|
@@:
|
|
mov eax,[esi]
|
|
add esi,4
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg ah,al
|
|
shr eax,cl
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg ah,al
|
|
mov [edi],eax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, 4 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_4_wide_rotated_no_last::
|
|
@@:
|
|
mov ax,[esi]
|
|
xchg ah,al
|
|
shl eax,16
|
|
mov ah,[esi+2]
|
|
add esi,3
|
|
shr eax,cl
|
|
xchg ah,al
|
|
mov [edi+2],ax
|
|
shr eax,16
|
|
mov [edi+1],al
|
|
or [edi],ah
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 4 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_4_wide_rotated_no_last::
|
|
@@:
|
|
mov ax,[esi]
|
|
xchg ah,al
|
|
shl eax,16
|
|
mov ah,[esi+2]
|
|
add esi,3
|
|
shr eax,cl
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg ah,al
|
|
or [edi],eax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 4 bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_4_wide_rotated_no_last::
|
|
@@:
|
|
mov ax,[esi]
|
|
xchg ah,al
|
|
shl eax,16
|
|
mov ah,[esi+2]
|
|
add esi,3
|
|
shr eax,cl
|
|
xchg ah,al
|
|
ror eax,16
|
|
xchg ah,al
|
|
mov [edi],eax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, 4 bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_4_wide_unrotated::
|
|
@@:
|
|
mov eax,[esi]
|
|
add esi,4
|
|
mov [edi],eax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, 4 bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_4_wide_unrotated::
|
|
@@:
|
|
mov eax,[esi]
|
|
add esi,4
|
|
or [edi],eax
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, n bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_N_wide_rotated_need_last::
|
|
mov eax,ulWidthInBytes
|
|
mov edx,ulBufDelta
|
|
sub edx,eax
|
|
mov ulTmpDstDelta,edx
|
|
dec eax ;source doesn't advance after first byte, and
|
|
; we do the first byte outside the loop
|
|
mov edx,ulGlyDelta
|
|
sub edx,eax
|
|
mov ulTmpSrcDelta,edx
|
|
mov ulTmpWidthInBytes,eax
|
|
ofNwrnl_scan_loop:
|
|
mov al,[esi] ;do the initial, ORed byte separately
|
|
shr al,cl
|
|
or [edi],al
|
|
inc edi
|
|
mov edx,ulTmpWidthInBytes
|
|
@@:
|
|
mov ax,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
mov [edi],ah
|
|
inc edi
|
|
dec edx
|
|
jnz @B
|
|
add esi,ulTmpSrcDelta
|
|
add edi,ulTmpDstDelta
|
|
dec ebx
|
|
jnz ofNwrnl_scan_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, n bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_N_wide_rotated_need_last::
|
|
mov eax,ulWidthInBytes
|
|
mov edx,ulBufDelta
|
|
sub edx,eax
|
|
mov ulTmpDstDelta,edx
|
|
dec eax ;source doesn't advance after first byte, and
|
|
; we do the first byte outside the loop
|
|
mov edx,ulGlyDelta
|
|
sub edx,eax
|
|
mov ulTmpSrcDelta,edx
|
|
mov ulTmpWidthInBytes,eax
|
|
oaNwrnl_scan_loop:
|
|
mov al,[esi] ;do the initial, ORed byte separately
|
|
shr al,cl
|
|
or [edi],al
|
|
inc edi
|
|
mov edx,ulTmpWidthInBytes
|
|
@@:
|
|
mov ax,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
or [edi],ah
|
|
inc edi
|
|
dec edx
|
|
jnz @B
|
|
add esi,ulTmpSrcDelta
|
|
add edi,ulTmpDstDelta
|
|
dec ebx
|
|
jnz oaNwrnl_scan_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, n bytes wide dest, rotated, need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_N_wide_rotated_need_last::
|
|
mov eax,ulWidthInBytes
|
|
mov edx,ulBufDelta
|
|
sub edx,eax
|
|
mov ulTmpDstDelta,edx
|
|
mov eax,ulWidthInBytes
|
|
dec eax ;source doesn't advance after first byte, and
|
|
; we do the first byte outside the loop
|
|
mov edx,ulGlyDelta
|
|
sub edx,eax
|
|
mov ulTmpSrcDelta,edx
|
|
mov ulTmpWidthInBytes,eax
|
|
mfNwrnl_scan_loop:
|
|
mov al,[esi] ;do the initial byte separately
|
|
shr al,cl
|
|
mov [edi],al
|
|
inc edi
|
|
mov edx,ulTmpWidthInBytes
|
|
@@:
|
|
mov ax,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
mov [edi],ah
|
|
inc edi
|
|
dec edx
|
|
jnz @B
|
|
add esi,ulTmpSrcDelta
|
|
add edi,ulTmpDstDelta
|
|
dec ebx
|
|
jnz mfNwrnl_scan_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR first byte, N bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_first_N_wide_rotated_no_last::
|
|
mov eax,ulWidthInBytes
|
|
dec eax ;one less because we don't advance after the
|
|
; last byte
|
|
mov edx,ulBufDelta
|
|
sub edx,eax
|
|
mov ulTmpDstDelta,edx
|
|
dec eax ;source doesn't advance after first byte, and
|
|
; we do the first & last bytes outside the
|
|
; loop; already subtracted 1 above
|
|
mov edx,ulGlyDelta
|
|
sub edx,eax
|
|
mov ulTmpSrcDelta,edx
|
|
mov ulTmpWidthInBytes,eax
|
|
ofNwr_scan_loop:
|
|
mov al,[esi] ;do the initial, ORed byte separately
|
|
shr al,cl
|
|
or [edi],al
|
|
inc edi
|
|
mov edx,ulTmpWidthInBytes
|
|
@@:
|
|
mov ax,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
mov [edi],ah
|
|
inc edi
|
|
dec edx
|
|
jnz @B
|
|
|
|
mov ah,[esi] ;do the final byte separately
|
|
sub al,al
|
|
shr eax,cl
|
|
mov [edi],al
|
|
|
|
add esi,ulTmpSrcDelta
|
|
add edi,ulTmpDstDelta
|
|
dec ebx
|
|
jnz ofNwr_scan_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, N bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_N_wide_rotated_no_last::
|
|
mov eax,ulWidthInBytes
|
|
dec eax ;one less because we don't advance after the
|
|
; last byte
|
|
mov edx,ulBufDelta
|
|
sub edx,eax
|
|
mov ulTmpDstDelta,edx
|
|
dec eax ;source doesn't advance after first byte, and
|
|
; we do the first & last bytes outside the
|
|
; loop; already subtracted 1 above
|
|
mov edx,ulGlyDelta
|
|
sub edx,eax
|
|
mov ulTmpSrcDelta,edx
|
|
mov ulTmpWidthInBytes,eax
|
|
oaNwr_scan_loop:
|
|
mov al,[esi] ;do the initial, ORed byte separately
|
|
shr al,cl
|
|
or [edi],al
|
|
inc edi
|
|
mov edx,ulTmpWidthInBytes
|
|
@@:
|
|
mov ax,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
or [edi],ah
|
|
inc edi
|
|
dec edx
|
|
jnz @B
|
|
|
|
mov ah,[esi] ;do the final byte separately
|
|
sub al,al
|
|
shr eax,cl
|
|
or [edi],al
|
|
|
|
add esi,ulTmpSrcDelta
|
|
add edi,ulTmpDstDelta
|
|
dec ebx
|
|
jnz oaNwr_scan_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, N bytes wide dest, rotated, don't need final source byte.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_N_wide_rotated_no_last::
|
|
mov eax,ulWidthInBytes
|
|
dec eax ;one less because we don't advance after the
|
|
; last byte
|
|
mov edx,ulBufDelta
|
|
sub edx,eax
|
|
mov ulTmpDstDelta,edx
|
|
dec eax ;source doesn't advance after first byte, and
|
|
; we do the first & last bytes outside the
|
|
; loop; already subtracted 1 above
|
|
mov edx,ulGlyDelta
|
|
sub edx,eax
|
|
mov ulTmpSrcDelta,edx
|
|
mov ulTmpWidthInBytes,eax
|
|
mfNwr_scan_loop:
|
|
mov al,[esi] ;do the initial byte separately
|
|
shr al,cl
|
|
mov [edi],al
|
|
inc edi
|
|
mov edx,ulTmpWidthInBytes
|
|
@@:
|
|
mov ax,[esi]
|
|
inc esi
|
|
ror ax,cl
|
|
mov [edi],ah
|
|
inc edi
|
|
dec edx
|
|
jnz @B
|
|
|
|
mov ah,[esi] ;do the final byte separately
|
|
sub al,al
|
|
shr eax,cl
|
|
mov [edi],al
|
|
|
|
add esi,ulTmpSrcDelta
|
|
add edi,ulTmpDstDelta
|
|
dec ebx
|
|
jnz mfNwr_scan_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; MOV first byte, N bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
mov_first_N_wide_unrotated::
|
|
mov edx,ulBufDelta
|
|
mov eax,ulWidthInBytes
|
|
sub edx,eax
|
|
shr eax,1 ;width in words
|
|
jc short odd_width ;there's at least one odd byte
|
|
shr eax,1 ;width in dwords
|
|
jc short two_odd_bytes ;there's an odd word
|
|
;copy width is a dword multiple
|
|
@@:
|
|
mov ecx,eax
|
|
rep movsd ;copy as many dwords as possible
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
odd_width::
|
|
shr eax,1 ;width in dwords
|
|
jc short three_odd_bytes ;there's an odd word and an odd byte
|
|
;there's just an odd byte
|
|
inc edx ;because we won't advance after last byte
|
|
@@:
|
|
mov ecx,eax
|
|
rep movsd ;copy as many dwords as possible
|
|
mov cl,[esi]
|
|
inc esi
|
|
mov [edi],cl
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
two_odd_bytes::
|
|
add edx,2 ;because we won't advance after last word
|
|
@@:
|
|
mov ecx,eax
|
|
rep movsd ;copy as many dwords as possible
|
|
mov cx,[esi]
|
|
add esi,2
|
|
mov [edi],cx
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
three_odd_bytes::
|
|
add edx,3 ;because we won't advance after last word/byte
|
|
@@:
|
|
mov ecx,eax
|
|
rep movsd ;copy as many dwords as possible
|
|
mov cx,[esi]
|
|
mov [edi],cx
|
|
mov cl,[esi+2]
|
|
add esi,3
|
|
mov [edi+2],cl
|
|
add edi,edx
|
|
dec ebx
|
|
jnz @B
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; OR all bytes, N bytes wide dest, unrotated.
|
|
;-----------------------------------------------------------------------;
|
|
or_all_N_wide_unrotated::
|
|
mov edx,ulBufDelta
|
|
mov eax,ulWidthInBytes
|
|
sub edx,eax
|
|
shr eax,1 ;width in words
|
|
jc short or_odd_width ;there's at least one odd byte
|
|
shr eax,1 ;width in dwords
|
|
jc short or_two_odd_bytes ;there's an odd word
|
|
;copy width is a dword multiple
|
|
or_no_odd_bytes_loop::
|
|
push ebx ;preserve scan count
|
|
mov ebx,eax
|
|
@@:
|
|
mov ecx,[esi]
|
|
add esi,4
|
|
or [edi],ecx
|
|
add edi,4 ;copy as many dwords as possible
|
|
dec ebx
|
|
jnz @B
|
|
add edi,edx
|
|
pop ebx ;restore scan count
|
|
dec ebx
|
|
jnz or_no_odd_bytes_loop
|
|
jmp pGlyphLoop
|
|
|
|
or_odd_width::
|
|
shr eax,1 ;width in dwords
|
|
jc short or_three_odd_bytes ;there's an odd word and an odd byte
|
|
;there's just an odd byte
|
|
inc edx ;skip over last byte too
|
|
or_one_odd_bytes_loop::
|
|
push ebx ;preserve scan count
|
|
mov ebx,eax
|
|
@@:
|
|
mov ecx,[esi]
|
|
add esi,4
|
|
or [edi],ecx
|
|
add edi,4 ;copy as many dwords as possible
|
|
dec ebx
|
|
jnz @B
|
|
mov cl,[esi]
|
|
or [edi],cl
|
|
inc esi
|
|
add edi,edx
|
|
pop ebx ;restore scan count
|
|
dec ebx
|
|
jnz or_one_odd_bytes_loop
|
|
jmp pGlyphLoop
|
|
|
|
or_two_odd_bytes::
|
|
add edx,2 ;skip over last 2 bytes too
|
|
or_two_odd_bytes_loop::
|
|
push ebx ;preserve scan count
|
|
mov ebx,eax
|
|
@@:
|
|
mov ecx,[esi]
|
|
add esi,4
|
|
or [edi],ecx
|
|
add edi,4 ;copy as many dwords as possible
|
|
dec ebx
|
|
jnz @B
|
|
mov cx,[esi]
|
|
or [edi],cx
|
|
add esi,2
|
|
add edi,edx
|
|
pop ebx ;restore scan count
|
|
dec ebx
|
|
jnz or_two_odd_bytes_loop
|
|
jmp pGlyphLoop
|
|
|
|
or_three_odd_bytes::
|
|
add edx,3 ;skip over last 3 bytes too
|
|
or_three_odd_bytes_loop::
|
|
push ebx ;preserve scan count
|
|
mov ebx,eax
|
|
@@:
|
|
mov ecx,[esi]
|
|
add esi,4
|
|
or [edi],ecx
|
|
add edi,4 ;copy as many dwords as possible
|
|
dec ebx
|
|
jnz @B
|
|
mov cx,[esi]
|
|
or [edi],cx
|
|
mov cl,[esi+2]
|
|
or [edi+2],cl
|
|
add esi,3
|
|
add edi,edx
|
|
pop ebx ;restore scan count
|
|
dec ebx
|
|
jnz or_three_odd_bytes_loop
|
|
jmp pGlyphLoop
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; At this point, the text is drawn to the temp buffer.
|
|
; Now, draw the extra rectangles to the temp buffer.
|
|
;
|
|
; Input:
|
|
; pdsurf = pointer to target surface (screen)
|
|
; prclText = pointer to text bounding rectangle
|
|
; prclOpaque = pointer to opaquing rectangle, if there is one
|
|
; iFgColor = text color
|
|
; iBgColor = opaquing rectangle color, if there is one
|
|
; ulTempLeft = X coordinate on dest of left edge of temp buffer pointed
|
|
; to by pTempBuffer
|
|
; pTempBuffer = pointer to first byte (upper left corner) of
|
|
; temp buffer into which we're drawing. This should be
|
|
; dword-aligned with the destination
|
|
; ulBufDelta = destination scan-to-scan offset
|
|
; Text drawn to temp buffer
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
glyphs_are_done::
|
|
extra_rects_are_done::
|
|
exit_fast_text::
|
|
|
|
cRet vFastText
|
|
|
|
endProc vFastText
|
|
|
|
public draw_f_tb_no_to_temp_start
|
|
public draw_nf_tb_no_to_temp_start
|
|
public draw_to_temp_start_entry
|
|
public draw_f_ntb_o_to_temp_start
|
|
public draw_nf_ntb_o_to_temp_start
|
|
public draw_to_temp_start_entry2
|
|
public draw_f_tb_no_to_temp_loop
|
|
public draw_nf_tb_no_to_temp_loop
|
|
public draw_to_temp_loop_entry
|
|
public draw_f_ntb_o_to_temp_loop
|
|
public draw_nf_ntb_o_to_temp_loop
|
|
public draw_to_temp_loop_entry2
|
|
public or_all_1_wide_rotated_need_last
|
|
public or_all_1_wide_rotated_no_last
|
|
public or_first_1_wide_rotated_need_last
|
|
public or_first_1_wide_rotated_no_last
|
|
public or_first_1_wide_rotated_loop
|
|
public mov_first_1_wide_rotated_need_last
|
|
public mov_first_1_wide_rotated_no_last
|
|
public mov_first_1_wide_rotated_loop
|
|
public mov_first_1_wide_unrotated
|
|
public mov_first_1_wide_unrotated_loop
|
|
public or_all_1_wide_unrotated
|
|
public or_all_1_wide_unrotated_loop
|
|
public or_first_2_wide_rotated_need_last
|
|
public or_first_2_wide_rotated_need_loop
|
|
public or_all_2_wide_rotated_need_last
|
|
public or_all_2_wide_rotated_need_loop
|
|
public mov_first_2_wide_rotated_need_last
|
|
public mov_first_2_wide_rotated_need_loop
|
|
public or_first_2_wide_rotated_no_last
|
|
public or_first_2_wide_rotated_loop
|
|
public or_all_2_wide_rotated_no_last
|
|
public or_all_2_wide_rotated_loop
|
|
public mov_first_2_wide_rotated_no_last
|
|
public mov_first_2_wide_rotated_loop
|
|
public mov_first_2_wide_unrotated
|
|
public mov_first_2_wide_unrotated_loop
|
|
public or_all_2_wide_unrotated
|
|
public or_all_2_wide_unrotated_loop
|
|
public or_first_3_wide_rotated_need_last
|
|
public or_all_3_wide_rotated_need_last
|
|
public mov_first_3_wide_rotated_need_last
|
|
public or_first_3_wide_rotated_no_last
|
|
public or_all_3_wide_rotated_no_last
|
|
public mov_first_3_wide_rotated_no_last
|
|
public mov_first_3_wide_unrotated
|
|
public or_all_3_wide_unrotated
|
|
public or_first_4_wide_rotated_need_last
|
|
public or_all_4_wide_rotated_need_last
|
|
public mov_first_4_wide_rotated_need_last
|
|
public or_first_4_wide_rotated_no_last
|
|
public or_all_4_wide_rotated_no_last
|
|
public mov_first_4_wide_rotated_no_last
|
|
public mov_first_4_wide_unrotated
|
|
public or_all_4_wide_unrotated
|
|
public or_first_N_wide_rotated_need_last
|
|
public or_all_N_wide_rotated_need_last
|
|
public mov_first_N_wide_rotated_need_last
|
|
public or_first_N_wide_rotated_no_last
|
|
public or_all_N_wide_rotated_no_last
|
|
public mov_first_N_wide_rotated_no_last
|
|
public mov_first_N_wide_unrotated
|
|
public odd_width
|
|
public two_odd_bytes
|
|
public three_odd_bytes
|
|
public or_all_N_wide_unrotated
|
|
public or_no_odd_bytes_loop
|
|
public or_odd_width
|
|
public or_one_odd_bytes_loop
|
|
public or_two_odd_bytes
|
|
public or_two_odd_bytes_loop
|
|
public or_three_odd_bytes
|
|
public or_three_odd_bytes_loop
|
|
public glyphs_are_done
|
|
public exit_fast_text
|
|
|
|
_TEXT$01 ends
|
|
|
|
end
|