;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        page    ,132

;/*****************************************************************************
;*
;* SOURCE FILE NAME = POLYBITM.ASM
;*
;* DESCRIPTIVE NAME = Polyline bitmap line drawing device driver.
;*
;*
;* VERSION      V2.0
;*
;* DATE         03/30/87
;*
;* DESCRIPTION
;*
;*     This module contains all of the routines called by POLYLINE.ASM
;*     to draw solid polylines in memory bitmaps.  The routines are basically
;*     broken into six different cases.  Lines are categorized as x major,
;*     y major or diagonal.  They are also broken down into simple and
;*     non-simple, or standard, cases; where simple means horizontal, vertical
;*     or on a diagonal.  These simple cases can be drawn much faster than
;*     the standard cases, and are therefore broken out from the rest.
;*
;*     There are similar routines in PLYSOLID.ASM for solid lines to the EGA,
;*     and POLYSTYL.ASM for styled lines to EGA or bitmaps.  While these
;*     routines are all quite similar, they are separated purely for speed
;*     considerations.  POLYLINE.ASM is the dispatching module for all of
;*     these routines, and the run length slice algorithm DDA, which all of
;*     these routines are based on, is explained in that module.
;*
;*     Near the end of this module, there are three output routines.
;*     bm_set_to_zero sets masked bits in the destination byte to zeros.
;*     bm_set_to_one sets masked bits in the destination byte to ones.
;*     bm_not_dest inverts the masked bits in the destination byte.  The
;*     address of one of these routines, or zero, in the case where we want
;*     to do nothing, is loaded into BitmapProc.  Then when drawing lines in
;*     a bitmap, BitmapProc is called to output each byte to the bitmap.
;*
;*     At the end of this module, there are two routines, check_segment_overflow
;*     and dont_check_overflow.  The address of check_segment_overflow is loaded
;*     into OverflowProc if the destination is a huge bitmap and the line being
;*     drawn is in multiple segments.  Otherwise dont_check_overflow is loaded
;*     into OverflowProc.  The first routine checks and corrects for segment
;*     overflow.  The second routine simply does a near return.  Such a
;*     complicated routine as this might seem strange, but it allows us to us
;*     the same code for huge and small bitmaps, with minimal speed change.
;*
;*     Huge bitmaps are stored on a scan line basis.  For example, if we have
;*     three color planes, the the bitmap is stored as a red scan line, a green
;*     scan line, a blue scan line, a red scan line, and so on.  Because of this
;*     format, there will most likely be some left over bytes at the end of the
;*     segment.  These will have to be accounted for when crossing segment
;*     boundaries.
;*
;*
;* FUNCTIONS    setup_poly_frame_1
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   03/30/87                     Written by Kent Settle   (kentse)
;*
;*****************************************************************************/


        .386

        .xlist

INCL_DDIPATHS   equ     1
DINCL_ENABLE            equ     1
DINCL_BITMAP            equ     1

        include pmgre.inc
        include driver.inc
        include display.inc
        include polyline.inc
        include extern.inc
        include protos.inc

        .list

        .MODEL FLAT

        ASSUME  CS:FLAT,SS:FLAT,DS:FLAT,ES:FLAT

        .DATA

EXTERNDEF       Origin_bank:BYTE

Bitmap_Rop_Table        equ                      this DWORD
        DWORD   bm_black
        DWORD   bm_ornot
        DWORD   bm_notand
        DWORD   bm_notpen
        DWORD   bm_andnot
        DWORD   bm_notdst
        DWORD   bm_xor
        DWORD   bm_dpan
        DWORD   bm_dpa
        DWORD   bm_dpxn
        DWORD   bm_d
        DWORD   bm_dpno
        DWORD   bm_p
        DWORD   bm_pdno
        DWORD   bm_dpo
        DWORD   bm_white

        .CODE

        OPTION PROLOGUE:None

        OPTION EPILOGUE:None

;/***************************************************************************
;*
;* FUNCTION NAME = setup_poly_frame_1
;*
;* DESCRIPTION   = This function is just a grouping of the following
;*                 public labels:
;*
;*                      bitmap_solid_horizontal
;*                      bitmap_solid_vertical
;*                      bitmap_solid_diagonal
;*                      bitmap_styled_horizontal
;*                      bitmap_styled_vertical
;*                      bitmap_styled_diagonal
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

setup_poly_frame_1  PROC SYSCALL
  LOCAL   returnvalue:DWORD,
          dwStyleCounter:DWORD,
          Flags:DWORD,
          Count:DWORD,
          Points:DWORD
  LOCAL   npddc:DWORD,
          dwStyleMask:DWORD,
          npfnUnSetup:DWORD,
          CurLineColor:DWORD,
          DrawModeIndex:DWORD,
          cPlanes:DWORD
  LOCAL   cbNextPlane:DWORD,
          dwBitmapROP:DWORD,
          dwStyleStepHorz:DWORD,
          dwStyleStepVert:DWORD,
          dwStyleStepDiag:DWORD
  LOCAL   dwStyleStepHorzTmp:DWORD,
          dwStyleStepVertTmp:DWORD,
          offNextLine:DWORD,
          cbScanSize:DWORD,
          cbHugeScanWrap:DWORD,
          cySurface:DWORD
  LOCAL   cScansPerSegment:DWORD,
          pSurfaceStart:DWORD,
          anpfnRunRoutines:DWORD,
          LineStyle:DWORD,
          npfnPassSetup:DWORD,
          cPasses:DWORD,
          lsg:LINESEGMENT
  LOCAL   dwStyleStepRun:DWORD,
          dwStyleStepSide:DWORD,
          dwActiveStyleCounter:DWORD,
          dwActiveStyleMask:DWORD,
          yA:DWORD,
          cScans:DWORD,
          cA:DWORD,
          cB:DWORD,
          cm:DWORD
  LOCAL   npfnRunRoutine:DWORD,
          iWhichDDA:DWORD,
          dwError:DWORD,
          dwFracS:DWORD,
          dwRotBitMask:DWORD,
          cbScanAddressDelta:DWORD,
          cbSideStepAddressDelta:DWORD,
          cbHugeScanDelta:DWORD,
          selHugeDelta:DWORD,
          dwScan:DWORD
  LOCAL   pSurfaceAddress:DWORD,
          cTmpScans:DWORD,
          dwTmpError:DWORD,
          dwTmpScan:DWORD,
          dwTmpRotBitMask:DWORD,
          dwTmpActiveStyleCounter:DWORD,
          dwTmpActiveStyleMask:DWORD,
          cTmpPasses:DWORD,
          TmpCurLineColor:DWORD
  LOCAL                    Destination_device:byte

        public  bitmap_solid_horizontal

;/***************************************************************************
;*
;* PUBLIC ROUTINE  bitmap_solid_horizontal
;*
;* DESCRIPTION   = Draws a solid horizontal line into a bitmap.
;*
;*                  Registers Destroyed:
;*                        CX,SI
;*                  Registers Preserved:
;*                        DX,BP,ES
;*
;* INPUT         = DS:DI = bitmap address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*
;* OUTPUT        = DS:DI = new bitmap address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/


bitmap_solid_horizontal::

;/*
;** Check color or mono, if color use other routine.
;*/

        cmp     cPlanes,1
        je      @F
        jmp     color_bitmap_solid_horizontal
@@:
        mov     esi,dwBitmapROP

;/*
;** calculate the start mask, end mask, and byte count
;*/

        dec     ecx                               ; CX = number of bits to move over
        mov     eax,ecx                           ; AX = ending bit number
        shr     eax,3                             ; AX = number of bytes to move
        and     ecx,7                             ; CX = number of bits to rotate
        mov     bh,bl                             ; BH = initial bit
        ror     bl,cl                             ; BL = ending bit
        mov     ecx,eax                           ; CX = number of bytes to move
        cmp     bh,bl                             ; adjust the count for byte wrap
        adc     ecx,0                             ; CX = bytes to touch - 1
        mov     al,bh                             ; AL = initial bit
        mov     bh,bl                             ; BH = ending bit
        neg     bh                                ; BH = ending mask
        add     al,al
        dec     al                                ; AL = initial mask
        jcxz    just_do_the_last

;/*
;** put out the first byte
;*/

        mov     ah,al
        and     ax,si
        not     al
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
        inc     edi

;/*
;** do any intermediate bytes
;*/

        dec     ecx
        jz      finish_up
        mov     eax,esi
        not     al

output_loop:

        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
        inc     edi
        loop    output_loop

;/*
;** do the last byte (combine end mask and previous mask)
;*/

finish_up:

        mov     al,0FFh

just_do_the_last:

        and     al,bh
        mov     ah,al
        and     eax,esi
        not     al
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
        ret

color_bitmap_solid_horizontal:
        push    ebx
        mov     al,byte ptr CurLineColor         ;set line color
        xor     ebx,ebx
        mov     ebx,DrawModeIndex
        mov     ebx,Bitmap_Rop_Table[ebx*4]
        jecxz   cbsh_line_done
cbsh_output_loop:

        call    ebx
        dec     ecx
        jecxz   cbsh_line_done
        inc     edi
        jmp     cbsh_output_loop
cbsh_line_done:
        pop     ebx
        ret


        public  bitmap_solid_vertical

;/***************************************************************************
;*
;* PUBLIC ROUTINE  bitmap_solid_vertical
;*
;* DESCRIPTION   = Draws a solid vertical line into a bitmap.
;*
;*                 Registers Destroyed:
;*                       CX,SI,DX
;*                 Registers Preserved:
;*                       BP,ES
;*
;* INPUT         = DS:DI = bitmap address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*
;* OUTPUT        = DS:DI = new bitmap address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/


bitmap_solid_vertical::

;/*
;** Check color or mono, if color use other routine.
;*/

        cmp     cPlanes,1
        je      @F
        jmp     color_bitmap_solid_vertical
@@:

        mov     esi,cbScanAddressDelta
        mov     edx,dwScan
        mov     al,bl                             ; get rotating bit mask
        mov     ah,al
        and     eax,dwBitmapROP
        not     al
        dec     ecx
        jz      bv_last_pixel

bv_loop:

;/*
;** output a pel
;*/

        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah

;/*
;** move to the next scan
;*/

        add     edi,esi
        dec     edx                               ; check for huge overflow
        loopnz  bv_loop
        jnz     bv_last_pixel

;/*
;** move to next huge scan
;*/

        add     edi,cbHugeScanDelta              ; wrap the surface address
        mov     edx,cScansPerSegment             ; reset wScan
        or      ecx,ecx
        jnz     bv_loop

;/*
;** do the last pel
;*/

bv_last_pixel:

        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
        mov     dwScan,edx
        ret

color_bitmap_solid_vertical:
        push    ebx
        mov     esi,cbScanAddressDelta
        mov     al,byte ptr CurLineColor         ;set line color
        xor     ebx,ebx
        mov     ebx,DrawModeIndex
        mov     ebx,Bitmap_Rop_Table[ebx*4]
        jecxz   cbsv_line_done
cbsv_output_loop:
        call    ebx
        dec     ecx
        jecxz   cbsv_line_done
        add     edi,esi
        jmp     cbsv_output_loop
cbsv_line_done:
        pop     ebx
        ret


        public  bitmap_solid_diagonal

;/***************************************************************************
;*
;* PUBLIC ROUTINE  bitmap_solid_diagonal
;*
;* DESCRIPTION   = Draws a solid diagonal line into a bitmap.
;*
;*                 Registers Destroyed:
;*                       CX,DX,SI
;*                 Registers Preserved:
;*                       BP,ES
;*
;* INPUT         = DS:DI = bitmap address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*
;* OUTPUT        = DS:DI = new EGA address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;*                       ----Pseudo-Code----
;* bitmap_solid_diagonal
;* {
;*    // this routine draws BitCount diagonal bits.  since we are drawing
;*    // a diagonal segment, x and y coordinates will change with each
;*    // bit drawn.
;*
;*    while (BitCount--)
;*    {
;*        output byte to bitmap memory;
;*        rotate bit mask;
;*        increment DI if done with byte;
;*        DI += AddVertStep;                 // jump to next scan line.
;*    }
;*
;*    BL = rotating bit mask;
;*                                           // return with BL = rotating bitmask,
;*    return();                              // DS:DI => current destination byte.
;* }
;*
;***************************************************************************/


bitmap_solid_diagonal::

;/*
;** Check color or mono, if color use other routine.
;*/

        cmp     cPlanes,1
        je      @F
        jmp     color_bitmap_solid_diagonal
@@:

        mov     esi,cbScanAddressDelta
        mov     edx,dwScan
        mov     al,bl                             ; get rotating bit mask
        mov     ah,al
        and     eax,dwBitmapROP
        not     al
        dec     ecx
        jz      bd_last_pixel

bd_loop:

;/*
;** output a pel
;*/

        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah

;/*
;** move to the next scan
;*/

        ror     al,1
        ror     ah,1
        ror     bl,1
        adc     edi,esi
        dec     edx                               ; check for huge overflow
        loopnz  bd_loop
        jnz     bd_last_pixel

;/*
;** move to next huge scan
;*/

        add     edi,cbHugeScanDelta              ; wrap the surface address
        mov     edx,cScansPerSegment             ; reset wScan
        or      ecx,ecx
        jnz     bd_loop

;/*
;** do the last pel
;*/

bd_last_pixel:
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
        mov     dwScan,edx
        ret

color_bitmap_solid_diagonal:
        push    ebx
        mov     esi,cbScanAddressDelta
        mov     al,byte ptr CurLineColor         ;set line color
        xor     ebx,ebx
        mov     ebx,DrawModeIndex
        mov     ebx,Bitmap_Rop_Table[ebx*4]
        jecxz   cbsd_line_done
cbsd_output_loop:
        call    ebx
        dec     ecx
        jecxz   cbsd_line_done
        inc     edi
        add     edi,esi
        jmp     cbsd_output_loop
cbsd_line_done:
        pop     ebx
        ret


        public  bitmap_styled_horizontal

;/***************************************************************************
;*
;* PUBLIC ROUTINE   bitmap_styled_horizontal
;*
;* DESCRIPTION   =  Draws a styled horizontal line into a bitmap.
;*
;*                  Registers Destroyed:
;*                        CX,SI
;*                  Registers Preserved:
;*                        DX,BP,ES
;*
;* INPUT         = DS:DI = bitmap address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*
;* OUTPUT        = DS:DI = new bitmap address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/


bitmap_styled_horizontal::

;/*
;** Check color or mono, if color use other routine.
;*/

        cmp     cPlanes,1
        je      @F
        jmp     color_bitmap_styled_horizontal
@@:

;/*
;**!!! special case LINETYPE_ALTERNATE for extra speed !!!
;*/

;/*
;** load all quantities into registers
;*/

        mov     al,bl                             ; AL = rotating bit mask
        mov     ah,al
        and     eax,dwBitmapROP
        not     al                                ; AX = AND mask, XOR mask
        mov     dl,BYTE PTR dwActiveStyleCounter ; DL = style error
        mov     bh,BYTE PTR dwActiveStyleMask  ; BH = style mask
        mov     esi,dwStyleStepHorz              ; SI = style step

;/*
;** run the loop
;*/

        dec     ecx
        jz      bsh_last_byte

bsh_loop:

;/*
;** draw the pixel if the mask says so
;*/

        or      bh,bh
        jns     @F
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
@@:

;/*
;** advance to the next pixel
;*/

        ror     al,1
        ror     ah,1
        ror     bl,1
        adc     edi,0

;/*
;** advance the style mask
;*/

        movzx   edx,dl
        add     edx,esi
        xchg    cl,dh
        rol     bh,cl
        mov     cl,dh
        loop    bsh_loop

;/*
;** draw the last pixel if the mask says so
;*/

bsh_last_byte:

        or      bh,bh
        jns     @F
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
@@:

;/*
;** unload all registers
;*/

        mov     BYTE PTR dwActiveStyleCounter,dl
        mov     BYTE PTR dwActiveStyleMask,bh
        ret

color_bitmap_styled_horizontal:
        push    ebx
        mov     dl,BYTE PTR dwActiveStyleCounter ;style error
        mov     ah,BYTE PTR dwActiveStyleMask  ; BH = style mask
        mov     esi,dwStyleStepHorz              ; SI = style step

        mov     al,byte ptr CurLineColor         ;set line color
        xor     ebx,ebx
        mov     ebx,DrawModeIndex
        mov     ebx,Bitmap_Rop_Table[ebx*4]
        jecxz   cbstyh_line_done
cbstyh_output_loop:
        or      ah,ah
        jns     @F
        call    ebx
@@:
        dec     ecx
        jecxz   cbstyh_line_done
        inc     edi

;/*
;** advance the style mask
;*/

        movzx   edx,dl
        add     edx,esi
        xchg    cl,dh
        rol     ah,cl
        mov     cl,dh

        jmp     cbstyh_output_loop
cbstyh_line_done:
        pop     ebx
        ret


        public  bitmap_styled_vertical

;/***************************************************************************
;*
;* PUBLIC ROUTINE   bitmap_styled_vertical
;*
;* DESCRIPTION   =  Draws a styled vertical line into a bitmap.
;*
;*                  Registers Destroyed:
;*                        CX,SI,DX
;*                  Registers Preserved:
;*                        BP,ES
;*
;* INPUT         = DS:DI = bitmap address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*
;* OUTPUT        = DS:DI = new bitmap address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/


bitmap_styled_vertical::

;/*
;** Check color or mono, if color use other routine.
;*/

        cmp     cPlanes,1
        je      @F
        jmp     color_bitmap_styled_vertical
@@:

        mov     esi,dwScan
        mov     dl,BYTE PTR dwActiveStyleCounter ; DL = style error
        mov     bh,BYTE PTR dwActiveStyleMask  ; BH = style mask
        mov     al,bl                             ; get rotating bit mask
        mov     ah,al
        and     eax,dwBitmapROP
        not     al
        dec     ecx
        jz      bsv_last_pixel

bsv_loop:

;/*
;** output a pel
;*/

        or      bh,bh
        jns     @F
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
@@:

;/*
;** advance the style mask
;*/

        movzx   edx,dl
        add     edx,dwStyleStepVert
        xchg    cl,dh
        rol     bh,cl
        mov     cl,dh

;/*
;** move to the next scan
;*/

        add     edi,cbScanAddressDelta
        dec     esi
        loopnz  bsv_loop
        jnz     bsv_last_pixel

;/*
;** move to next huge scan
;*/

        add     edi,cbHugeScanDelta              ; wrap the surface address
        mov     esi,cScansPerSegment             ; reset wScan
        or      ecx,ecx
        jnz     bsv_loop

;/*
;** do the last pel
;*/

bsv_last_pixel:

        or      bh,bh
        jns     @F
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
@@:     mov     BYTE PTR dwActiveStyleCounter,dl
        mov     BYTE PTR dwActiveStyleMask,bh
        mov     dwScan,esi
        ret

color_bitmap_styled_vertical:
        push    ebx
        mov     dl,BYTE PTR dwActiveStyleCounter ; style error
        mov     ah,BYTE PTR dwActiveStyleMask  ; AH = style mask
        mov     esi,cbScanAddressDelta           ; SI = scan delta
        mov     al,byte ptr CurLineColor         ;set line color
        xor     ebx,ebx
        mov     ebx,DrawModeIndex
        mov     ebx,Bitmap_Rop_Table[ebx*4]
        jecxz   cbstyv_line_done
cbstyv_output_loop:
        or      ah,ah
        jns     cbstyv_blank
        call    ebx
cbstyv_blank:

;/*
;** advance the style mask
;*/
        movzx   edx,dl
        add     edx,dwStyleStepVert
        xchg    cl,dh
        rol     ah,cl
        mov     cl,dh

        dec     ecx
        jecxz   cbstyv_line_done
        add     edi,esi
        jmp     cbstyv_output_loop
cbstyv_line_done:
        mov     BYTE PTR dwActiveStyleCounter,dl
        mov     BYTE PTR dwActiveStyleMask,ah
        pop     ebx
        ret


        public  bitmap_styled_diagonal

;/***************************************************************************
;*
;* PUBLIC ROUTINE   bitmap_styled_diagonal
;*
;* DESCRIPTION   =  Draws a styled diagonal line into a bitmap.
;*
;*                   Registers Destroyed:
;*                         CX,DX,SI
;*                   Registers Preserved:
;*                         BP,ES
;*
;* INPUT         = DS:DI = bitmap address
;*                 BL = rotating bit mask
;*                 CX = number of bits to draw
;*
;* OUTPUT        = DS:DI = new EGA address
;*                 BL = new rotating bit mask
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;*                      -----Pseudo-Code--
;* bitmap_styled_diagonal
;* {
;*    // this routine draws BitCount diagonal bits.  since we are drawing
;*    // a diagonal segment, x and y coordinates will change with each
;*    // bit drawn.
;*
;*    while (BitCount--)
;*    {
;*        output byte to bitmap memory;
;*        rotate bit mask;
;*        increment DI if done with byte;
;*        DI += AddVertStep;                 // jump to next scan line.
;*    }
;*
;*    BL = rotating bit mask;
;*                                           // return with BL = rotating bitmask,
;*    return();                              // DS:DI => current destination byte.
;* }
;*
;**************************************************************************/


bitmap_styled_diagonal::

;/*
;** Check color or mono, if color use other routine.
;*/
        cmp     cPlanes,1
        je      @F
        jmp     color_bitmap_styled_diagonal
@@:

        mov     esi,dwScan
        mov     dl,BYTE PTR dwActiveStyleCounter ; DL = style error
        mov     bh,BYTE PTR dwActiveStyleMask  ; BH = style mask
        mov     al,bl                             ; get rotating bit mask
        mov     ah,al
        and     eax,dwBitmapROP
        not     al
        dec     ecx
        jz      bsd_last_pixel

bsd_loop:

;/*
;** output a pel
;*/

        or      bh,bh
        jns     @F
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
@@:

;/*
;** advance the style mask
;*/

        movzx   edx,dl
        add     edx,dwStyleStepDiag
        xchg    cl,dh
        rol     bh,cl
        mov     cl,dh

;/*
;** move to the next scan
;*/

        ror     ah,1
        ror     al,1
        ror     bl,1
        adc     edi,cbScanAddressDelta
        dec     esi
        loopnz  bsd_loop
        jnz     bsd_last_pixel

;/*
;** move to next huge scan
;*/

        add     edi,cbHugeScanDelta              ; wrap the surface address
        mov     esi,cScansPerSegment             ; reset wScan
        or      ecx,ecx
        jnz     bsd_loop

;/*
;** do the last pel
;*/

bsd_last_pixel:

        or      bh,bh
        jns     @F
        and     BYTE PTR [edi],al
        xor     BYTE PTR [edi],ah
@@:     mov     BYTE PTR dwActiveStyleCounter,dl
        mov     BYTE PTR dwActiveStyleMask,bh
        mov     dwScan,esi
        ret

color_bitmap_styled_diagonal:
        push    ebx
        mov     dl,BYTE PTR dwActiveStyleCounter ; style error
        mov     esi,dwScan
        mov     ah,BYTE PTR dwActiveStyleMask  ; BH = style mask
        mov     al,byte ptr CurLineColor         ;set line color
        xor     ebx,ebx
        mov     ebx,DrawModeIndex
        mov     ebx,Bitmap_Rop_Table[ebx*4]
        jecxz   cbstyd_line_done
cbstyd_output_loop:
        or      ah,ah
        jns     cbno_diag_pixel
        call    ebx
cbno_diag_pixel:

;/*
;** advance the style mask
;*/
        movzx   edx,dl
        add     edx,dwStyleStepDiag
        xchg    cl,dh
        rol     ah,cl
        mov     cl,dh

        dec     esi
        dec     ecx
        jecxz   cbstyd_line_done
        inc     edi
        add     edi,cbScanAddressDelta
        jmp     cbstyd_output_loop
cbstyd_line_done:
        mov     dwScan,esi
        mov     BYTE PTR dwActiveStyleCounter,dl
        mov     BYTE PTR dwActiveStyleMask,ah
        pop     ebx
        ret


bm_black::
        mov     byte ptr [edi],0h
        ret

bm_white::
        mov     byte ptr [edi],0ffh
        ret

bm_ornot::
        or      byte ptr [edi],al
        not     byte ptr [edi]
        ret

bm_notand::
        push    dx
        mov     dl,al
        not     dl
        and     byte ptr [edi],dl
        pop     dx
        ret

bm_notpen::
        push    dx
        mov     dl,al
        not     dl
        mov     byte ptr [edi],dl
        pop     dx
        ret

bm_andnot::
        not     byte ptr [edi]
        and     byte ptr [edi],al
        ret

bm_notdst::
        not     byte ptr [edi]
        ret

bm_xor::
        xor     byte ptr [edi],al
        ret

bm_dpan::
        and     byte ptr [edi],al
        not     byte ptr [edi]
        ret

bm_dpa::
        and     byte ptr [edi],al
        ret

bm_dpxn::
        xor     byte ptr [edi],al
        not     byte ptr [edi]
        ret

bm_d::
        ret

bm_dpno::
        push    dx
        mov     dl,al
        not     dl
        or      byte ptr [edi],al
        pop     dx
        ret

bm_p::
        mov     byte ptr [edi],al
        ret

bm_pdno::
        not     byte ptr [edi]
        or      byte ptr [edi],al
        ret

bm_dpo::
        or      byte ptr [edi],al
        ret


setup_poly_frame_1  ENDP

        end
