;*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 = plbmsup.asm
;*
;* DESCRIPTIVE NAME = Polyline drawing device driver, support routines for      
;*                    drawing to 8-bit color, packed pixel memory bitmaps.
;*
;*
;* VERSION      V2.0
;*
;* DATE         06/06/87
;*
;* DESCRIPTION  
;*
;*   This module contains all of the routines called by POLYLINE.ASM
;*   to draw polylines in memory bitmaps. There is a separate
;*   routine for each of the 6 cases.  The 6 cases come from the fact
;*   that lines can be styled or not, and the runs can be horizontal,
;*   vertical, or diagonal.
;*
;*   These routines only draw a small part of a line.  This small part is
;*   called a "run".  It is a straight piece of a line that is either
;*   purely vertical, purely horizontal, or purely diagonal.  All lines
;*   are represented as a series of one of these cases.
;*
;*   Lines are drawn from left to right.  So if a line moves from right
;*   to left, the endpoints are swapped and the line is drawn from left
;*   to right.
;*
;*   The details of this algorithm are explained in POLYLINE.ASM
;*
;* FUNCTIONS    setup_poly_frame_bms
;*              bitmap_solid_horizontal
;*              bitmap_solid_diagonal
;*              bitmap_solid_vertical
;*              bitmap_styled_horizontal
;*              bitmap_styled_diagonal
;*              bitmap_styled_vertical
;*              bm_polyline_init
;*              NullRoutine
;*              get_bm_info
;*
;* NOTES        NONE
;*                                            
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   06/06/87                     Author: Wes Rupel   (wesleyr)
;*   05/07/88                     Charles Whitmer [chuckwh] New variables for
;*                                the new PolyLine scheme.
;*   05/20/88                     Charles Whitmer [chuckwh] Derived all the
;*                                above for the case of clipped lines, which
;*                                Bresenham neglected to cover in his paper.
;*   06/20/88                     Bob Grudem [bobgru] Implemented the "max"
;*                                metric for line styling.
;*                                Wes Rupel [wesleyr] Lots of alteration while
;*                                porting to 8 bpp (bits-per-pixel) format from
;*                                EGA.
;*   06/21/88                     Wes Rupel [wesleyr] EGA --> 8-bit color/packed
;*                                pixel ==> Massive Changes.
;*   09/16/88                     Bob Grudem [bobgru] Assimilated the 256-color
;*                                subroutines into a single module for easier
;*                                maintenance.  The monochrome bitmap
;*                                subroutines are in PLMONOBM.ASM.
;*   10/04/88                     Bob Grudem [bobgru] Style step now treated as
;*                                16-bit quantity so LINETYPE_ALTERNATE works.
;*                                Bob Grudem [bobgru] Now saves BX, which caller
;*                                expects.
;*****************************************************************************/

        .xlist
        include cmacros.inc
INCL_DDIPATHS           equ                      1
INCL_GPIPRIMITIVES      equ                      1
        include pmgre.inc
DINCL_ROPS      equ     1
        include driver.inc
        include display.inc
        include polyline.inc
        include njmp.mac
        include assert.mac
        .list

        public  get_bm_info
        public  bm_polyline_init

        externFP        DosGetSeg

sBegin  Code
        assumes cs,Code

        externW         monoBM_ROPmask_table      ; PLMONOBM.ASM
        externW         mono_bitmap_styled_table ; PLMONOBM.ASM
        externW         mono_bitmap_solid_table  ; PLMONOBM.ASM

;/*
;** the various line rendering routines
;*/

bitmap_styled_table     equ                      this word
        dw      bitmap_styled_horizontal
        dw      bitmap_styled_vertical
        dw      bitmap_styled_diagonal
        dw      bitmap_styled_diagonal

bitmap_solid_table      equ                      this word
        dw      bitmap_solid_horizontal
        dw      bitmap_solid_vertical
        dw      bitmap_solid_diagonal
        dw      bitmap_solid_diagonal


;/*
;** Color Bitmap Masks
;**
;** The colorBM_ROPmask_table contains and-masks and xor-masks for doing
;** the Mix logic.  See the comments in bm_polyline_init for further
;** explanation.
;*/

colorBM_ROPmask_table       equ     this word

;/*
;**                AND     XOR                       ROP
;**                --------------------
;*/
        db       00h,    00h                     ; DDx
        db        1h,     2h                     ; DPon (2 means NOT P)
        db        2h,    00h                     ; DPna
        db       00h,     2h                     ; Pn
        db        1h,     1h                     ; PDna (1 means P)
        db      0FFh,   0FFh                     ; Dn
        db      0FFh,     1h                     ; DPx
        db        1h,   0FFh                     ; DPan

        db        1h,    00h                     ; DPa
        db      0FFh,     2h                     ; DPxn
        db      0FFh,    00h                     ; D
        db        1h,     2h                     ; DPno
        db       00h,     1h                     ; P
        db        2h,   0FFh                     ; PDno
        db        2h,     1h                     ; DPo
        db       00h,   0FFh                     ; DDxn

        .errnz  ROP_DDX  - 0
        .errnz  ROP_DPON - 1
        .errnz  ROP_DPNA - 2
        .errnz  ROP_PN   - 3
        .errnz  ROP_PDNA - 4
        .errnz  ROP_DN   - 5
        .errnz  ROP_DPX  - 6
        .errnz  ROP_DPAN - 7
        .errnz  ROP_DPA  - 8
        .errnz  ROP_DPXN - 9
        .errnz  ROP_D    - 10
        .errnz  ROP_DPNO - 11
        .errnz  ROP_P    - 12
        .errnz  ROP_PDNO - 13
        .errnz  ROP_DPO  - 14
        .errnz  ROP_DDXN - 15


cProc   setup_poly_frame_bms,<FAR,NODATA>
        include plylocal.inc                      
cBegin  nogen
cEnd    nogen

;/*
;** here are two working implemenations of line mix modes:
;**
;** o  One uses an AND and an XOR mask
;**      This is the only method implemented for mono bitmaps
;**      and for styled lines to color bitmaps.
;**
;** o  The other calls separate innerloops for each raster op.
;**      This is done only for solid lines to color bitmaps.
;**      It uses about 140 bytes more than the AND-XOR method.
;**      It has an extra call/ret for each RUN.
;**      On common simple rops like PatCopy this method makes only
;**      one memory reference per PEL, whereas the AND-XOR makes four.
;*/



ifdef   USE_AND_XOR     ;--------------------------------=-=-=-=----<<<<
else

;/*
;** Bitmap Raster Logic.
;*/

?mix_DDx         macro
        mov     byte ptr [di],0
        endm

?mix_DPon        macro
        or      byte ptr [di],al
        not     byte ptr [di]
        endm
?mix_DPna        macro
        mov     ah,al
        not     ah                                ;; reverse pattern at init time
        and     byte ptr [di],ah                  ;; and choose DPa instead?
        endm
?mix_Pn          macro
        mov     ah,al                             ;; reverse pattern at init time
        not     ah                                ;; and choose P instead?
        mov     byte ptr [di],ah
        endm
?mix_PDna        macro
        not     byte ptr [di]
        and     byte ptr [di],al
        endm
?mix_Dn          macro
        not     byte ptr [di]
        endm
?mix_DPx         macro
        xor     byte ptr [di],al
        endm
?mix_DPan        macro
        and     byte ptr [di],al
        not     byte ptr [di]
        endm
?mix_DPa         macro
        and     byte ptr [di],al
        endm
?mix_DPxn        macro
        xor     byte ptr [di],al
        not     byte ptr [di]
        endm
?mix_D           macro
        endm
?mix_DPno        macro
        mov     ah,al                             ;; reverse pattern at init time
        not     ah                                ;; and choose DPo instead?
        or      byte ptr [di],ah
        endm
?mix_P           macro
        mov     byte ptr [di],al
        endm
?mix_PDno        macro
        not     byte ptr [di]
        or      byte ptr [di],al
        endm
?mix_DPo         macro
        or      byte ptr [di],al
        endm
?mix_DDxn        macro
        mov     byte ptr [di],0FFh
        endm

        irp     rop,<DDx,DPon,DPna,Pn,PDna,Dn,DPx,DPan,DPa,DPxn,D,DPno,P,PDno,DPo,DDxn>
ifdef ?mix_&rop
ifdef DEBUG
        public  mix_&rop
endif
mix_&rop&:
        ?mix_&rop                                ;; output a pel
        add     di,si                            ;; move to the next pel
        dec     dx                               ;; check for huge overflow
        loopnz  mix_&rop&                        ;; fall thru if either CX or DX are zeroed
        ret
else
        ??error2  <bitmap logic innerloop - unknown keyword rop>
endif
        endm

        public  mix_routine_table
mix_routine_table   equ     this word
        dw      mix_DDx
        dw      mix_DPon
        dw      mix_DPna
        dw      mix_Pn
        dw      mix_PDna
        dw      mix_Dn
        dw      mix_DPx
        dw      mix_DPan
        dw      mix_DPa
        dw      mix_DPxn
        dw      mix_D
        dw      mix_DPno
        dw      mix_P
        dw      mix_PDno
        dw      mix_DPo
        dw      mix_DDxn
        .errnz  ROP_DDX  - 0
        .errnz  ROP_DPON - 1
        .errnz  ROP_DPNA - 2
        .errnz  ROP_PN   - 3
        .errnz  ROP_PDNA - 4
        .errnz  ROP_DN   - 5
        .errnz  ROP_DPX  - 6
        .errnz  ROP_DPAN - 7
        .errnz  ROP_DPA  - 8
        .errnz  ROP_DPXN - 9
        .errnz  ROP_D    - 10
        .errnz  ROP_DPNO - 11
        .errnz  ROP_P    - 12
        .errnz  ROP_PDNO - 13
        .errnz  ROP_DPO  - 14
        .errnz  ROP_DDXN - 15
        public  MixRout_tblSize
MixRout_tblSize equ     $ - mix_routine_table

endif  ;USE_AND_XOR     ;--------------------------------=-=-=-=----<<<<

        public  bitmap_solid_horizontal

;/***************************************************************************
;*
;* PUBLIC ROUTINE  bitmap_solid_horizontal 
;*
;* DESCRIPTION   = Draws a solid horizontal line into a bitmap.
;*
;*                  Registers Destroyed: 
;*                        AX,CX,DX,SI                                   
;*                  Registers Preserved:                                
;*                        BX,BP,ES        NOTE, BX is available for use 
;*
;* INPUT         = DS:DI = bitmap address      
;*                 CX = number of bits to draw 
;*
;* OUTPUT        = DS:DI = new bitmap address 
;*                 
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing


ifdef   USE_AND_XOR     ;--------------------------------=-=-=-=----<<<<

bitmap_solid_horizontal    proc    near
        assert  cx,A,0
        mov     ax,wBitmapROP
bh_loop:
        and     byte ptr [di],al                  ; output a pel
        xor     byte ptr [di],ah
        inc     di                                ; move to the next pel
        loop    bh_loop
        dec     di
        ret
bitmap_solid_horizontal    endp

else                    ;--------------------------------=-=-=-=----<<<<

bitmap_solid_horizontal    proc    near
        assert  cx,A,0
        mov     al,CurLineColor
        mov     dx,cx
        mov     si,1
        call    npfnMixTheBits
        dec     di
        ret
bitmap_solid_horizontal    endp

endif                   ;--------------------------------=-=-=-=----<<<<

        public  bitmap_solid_diagonal
        public  bitmap_solid_vertical

;/***************************************************************************
;*
;* PUBLIC ROUTINES bitmap_solid_vertical
;*                 bitmap_solid_diagonal
;* DESCRIPTION   = Draws a solid vertical (or diagonal) line into a bitmap.
;*
;*                 Registers Destroyed:  
;*                       CX,SI,DX        
;*                 Registers Preserved:  
;*                       BP,ES           
;*
;* INPUT         = DS:DI = bitmap address      
;*                 CX = number of bits to draw 
;*
;* OUTPUT        = DS:DI = new bitmap address   
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing

ifdef   USE_AND_XOR     ;--------------------------------=-=-=-=----<<<<

bitmap_solid_diagonal    proc                     near
ifdef FIREWALLS
        nop     ; to separate the labels for debugging purposes.
endif
bitmap_solid_vertical    proc                     near
        assert  cx,A,0
        mov     si,cbScanAddressDelta
        mov     dx,cScansLeftInSeg
        mov     ax,wBitmapROP
bv_loop:
        and     byte ptr [di],al  ; output a pel
        xor     byte ptr [di],ah
        add     di,si                              ; move to the next pel
        dec     dx                                 ; check for huge overflow
        loopnz  bv_loop                            ; fall thru if either CX or DX are zeroed
        jcxz    bv_done

;/*
;** move to next huge scan (DX is 0, but CX is not)
;*/

        mov     dx,ds                             ; advance the segment
        add     dx,selHugeDelta
        mov     ds,dx
        assumes ds,nothing
        add     di,cbHugeScanDelta               ; wrap the surface address
        mov     dx,cScansPerSegment              ; reset cScansLeftInSeg
        or      cx,cx
        jnz     bv_loop

bv_done:
        sub     di,si
        inc     dx
        mov     cScansLeftInSeg,dx
        ret
bitmap_solid_vertical    endp
bitmap_solid_diagonal    endp

else                    ;--------------------------------=-=-=-=----<<<<

bitmap_solid_diagonal    proc                     near
ifdef FIREWALLS
        nop     ; to separate the labels for debugging purposes.
endif
bitmap_solid_vertical    proc                     near
        assert  cx,A,0
        mov     si,cbScanAddressDelta
        mov     dx,cScansLeftInSeg
        mov     al,CurLineColor
bv_loop:
        call    npfnMixTheBits
        jcxz    bv_done

;/*
;** move to next huge scan (DX is 0, but CX is not)
;*/

        mov     dx,ds                             ; advance the segment
        add     dx,selHugeDelta
        mov     ds,dx
        assumes ds,nothing
        add     di,cbHugeScanDelta               ; wrap the surface address
        mov     dx,cScansPerSegment              ; reset cScansLeftInSeg
        or      cx,cx
        jnz     bv_loop

bv_done:
        sub     di,si
        inc     dx
        mov     cScansLeftInSeg,dx
        ret
bitmap_solid_vertical    endp
bitmap_solid_diagonal    endp

endif                   ;--------------------------------=-=-=-=----<<<<

        public  bitmap_styled_horizontal

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

        assumes ds,nothing
        assumes es,nothing

bitmap_styled_horizontal    proc    near
        push    bx

        assert  cx,A,0

        mov     dl,bActiveStyleCounter           ; DL = style error
        mov     bh,bActiveStyleMask              ; BH = style mask
        mov     si,wStyleStepHorz                ; SI = style step

        mov     ax,wBitmapROP
bsh_loop:

;/*
;** draw the pixel if the style mask's high bit is "1"
;*/

        or      bh,bh
        jns     @F
        and     [di],al
        xor     [di],ah
@@:

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

        inc     di                                ; move to the next pel

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

        xor     dh,dh
        add     dx,si
        xchg    cl,dh                            ; put style overflow in CL, while saving CL
        rol     bh,cl                            ; rotate mask 0 or 1 bits (based on overflow)
        mov     cl,dh                            ; restore CL

        loop    bsh_loop

;/*
;** set/save exit state
;*/

        dec     di
        xor     cl,cl                            ; 
        xor     dh,dh                            ; unStep
        sub     dx,si                            ; StyleCounter
        adc     cl,0                             ; and
        ror     bh,cl                            ; StyleMask
        mov     bActiveStyleCounter,dl
        mov     bActiveStyleMask,bh

        pop     bx
        ret
bitmap_styled_horizontal    endp

        public  bitmap_styled_vertical

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

        assumes ds,nothing
        assumes es,nothing

bitmap_styled_diagonal    proc                     near
        push    bx
        mov     si,wStyleStepDiag
        jmp     short   enter_vert               ; must jump to avoid stack imbalance
                                                  ; i.e. can't use jmpnext trick
bitmap_styled_vertical    proc                     near
        push    bx
        mov     si,wStyleStepVert

enter_vert:
        assert  cx,A,0
        mov     dl,bActiveStyleCounter           ; DL = style "error"
        mov     bh,bActiveStyleMask              ; BH = style mask
        mov     ax,wBitmapROP
bsv_loop:

;/*
;** output a pel if the style mask's high bit is "1"
;*/

        or      bh,bh
        jns     @F
        and     [di],al
        xor     [di],ah
@@:

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

        xchg    cx,dx                            ; save CX, put DL in CL
        xor     ch,ch                            ; clear byte overflow indicator
        add     cx,si                            ; add in style step
        xchg    cl,ch                            ; put byte overflow bit into CL
        rol     bh,cl                            ; rotate mask if overflow
        xchg    cx,dx                            ; restore CX
        mov     dl,dh                            ; put style counter back in DL

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

        add     di,cbScanAddressDelta            ; move to the next pel
        dec     cScansLeftInSeg                  ; check for huge overflow

        loopnz  bsv_loop                           ; fall thru if either CX or SI are zeroed
        jcxz    bsv_done

;/*
;** move to next huge scan (SI is 0, but CX is not)
;*/

        push    si
        mov     si,ds                             ; advance the segment
        add     si,selHugeDelta
        mov     ds,si
        assumes ds,nothing
        add     di,cbHugeScanDelta               ; wrap the surface address
        mov     si,cScansPerSegment              ; reset cScansLeftInSeg
        mov     cScansLeftInSeg,si
        pop     si
        or      cx,cx
        jnz     bsv_loop

bsv_done:

;/*
;** set/save exit state
;*/

        inc     cScansLeftInSeg

        xor     cl,cl                            ; unStep
        xor     dh,dh                            ; StyleCounter
        sub     dx,si                            ; 
        adc     cl,0                             ; and
        ror     bh,cl                            ; StyleMask
        sub     di,cbScanAddressDelta
        mov     bActiveStyleCounter,dl
        mov     bActiveStyleMask,bh

        pop     bx
        ret
bitmap_styled_vertical    endp
bitmap_styled_diagonal    endp

        public  bitmap_styled_diagonal

;/***************************************************************************
;*
;* PUBLIC ROUTINE   bitmap_styled_diagonal  
;*
;* DESCRIPTION   =  Draws a styled diagonal line into a bitmap.                     
;*
;*                   Registers Destroyed:     
;*                         AX,BX,CX,DX,SI     
;*                   Registers Preserved:     
;*                         BP,ES              
;*
;* INPUT         = DS:DI = bitmap address      
;*                 CX = number of bits to draw 
;*                 
;* OUTPUT        = DS:DI = new EGA address      
;*
;* 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.
;* }
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing

;/***************************************************************************
;*
;* PUBLIC ROUTINE  bm_polyline_init
;*
;* DESCRIPTION   = Initializes stack frame variables for drawing lines to a     
;*                 bitmap.
;*
;*                  Registers Destroyed:    
;*                        AX,BX,CX          
;*                  Registers Preserved:    
;*                        DX,DI,SI,BP,ES    
;*                  Calls:
;*                        get_bm_info
;*
;* INPUT         = DS:DI = DDC                     
;*                 DS:SI = sd (surface definition) 
;*                 
;* OUTPUT        = DS = first segment of bitmap 
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

bm_polyline_init        proc                     near

        call    get_bm_info                       ; takes DS:DI = DDC
        assumes ds,nothing

        mov     bx,DrawModeIndex                 ; get the raster op
        test    sd_flags,SD_COLOR
        jnz     not_mono

;/*
;**  MonoChrome Bitmap Raster Ops
;** 
;**  We are dealing with a monochrome bitmap.  We therefore have only one
;**  bit of color info (the MONO_BIT).  The number we store for the mix
;**  mode is such that the ROPs are defined by the following table:
;** 
;**    P   D  ROP
;**   --- --- ---       P = Pattern (in our case it is the 1 bit of color info)
;**    1   1   a        D = Destination
;**    1   0   b
;**    0   1   c        a,b,c and d are bits (a is most significant) which
;**    0   0   d        give a 4-bit number we call the ROP.
;** 
;**  If P = 0 then a and b are not relevant, and we can list all 16 ROPs
;**  like this:
;**                      (P = 0)                         Do to Dest
;**                                                      -----------
;**                     / ab00   =>     set to 0
;**                 ROP/  ab01   =>     toggle
;**                    \  ab10   =>     leave alone
;**                     \ ab11   =>     set to 1
;** 
;**  If P = 1 then c and d are not relevant, and we can list all 16 ROPs
;**  like this:
;** 
;**                      (P = 1)                         Do to Dest
;**                                                      -----------
;**                     / 00cd   =>     set to 0
;**                 ROP/  01cd   =>     toggle
;**                    \  10cd   =>     leave alone
;**                     \ 11cd   =>     set to 1
;** 
;**  So if P = 1 we shift the ROP right two bits, then we look
;**  at the lower two bits two decide which of the 4 actions to
;**  take on our bitmap.
;*/

        mov     al,CurLineColorStatus
        shr     al,1                              ; MONO_BIT (P) --> CF ;!!!
        .errnz  High MONO_BIT - 00000001b         
        jnc     set_the_standard_proc
        shr     bx,2
set_the_standard_proc:
        and     bx,3
        add     bx,bx                              ; make a word ptr
        mov     ax,monoBM_ROPmask_table[bx]        ; add index into table
        mov     wBitmapROP,ax                      ; set up write logic

;/*
;** decide which set of run routines to use
;*/

        mov     ax,CodeOFFSET mono_bitmap_solid_table
        cmp     LineStyle,LINETYPE_SOLID - 1
        jz      @F
        mov     ax,CodeOFFSET mono_bitmap_styled_table
@@:     mov     anpfnRunRoutines,ax
        jmp     short   done_with_mono
not_mono:

publab  color_raster

;/*
;**  Color Bitmap Raster Ops
;** 
;**  The "mixes" or "raster ops" are accomplished by using an AND and an
;**  XOR mask in the (single) innerloop.  So to output a byte (pel) we
;**  would do this:
;**        and     byte ptr [di],al
;**        xor     byte ptr [di],ah
;**  The masks AL and AH are given in the following table:
;** 
;**        ROP     AND     XOR
;**       ------  -----   -----
;**        DDx     00      00
;**        DPon    ^P      ^P                       (^P means NOT P)
;**        DPna    ^P      00
;**        Pn      00      ^P
;**        PDna     P       P
;**        Dn      FF      FF
;**        DPx     FF       P
;**        DPan     P      FF
;** 
;**        DPa      P      00
;**        DPxn    FF      ^P
;**        D       FF      00
;**        DPno     P      ^P
;**        P       00       P
;**        PDno    ^P      FF
;**        DPo     ^P       P
;**        DDxn    00      FF
;** 
;**  The table can hold 00 and FF normally, but since the pattern
;**  (i.e. the color) is not known at compile time we will store "1" to
;**  mean P and "2" to mean ^P.
;*/

        add     bx,bx                             ; make index from raster op
ifdef   USE_AND_XOR     ;--------------------------------=-=-=-=----<<<<
else
        assert  bx,B,MixRout_tblSize
        mov     ax,mix_routine_table[bx]
        mov     npfnMixTheBits,ax
endif  ;USE_AND_XOR     ;--------------------------------=-=-=-=----<<<<

        mov     ax,colorBM_ROPmask_table[bx]     ; get AND and XOR masks
        cmp     al,1
        jl      got_AND_mask                     ; jump if it is 00 or FF
        mov     al,CurLineColor                  ; AL is 1 or 2 so get "P"
        je      got_AND_mask
        not     al                               ; AL was 2 so we want NOT P
 got_AND_mask:
        cmp     ah,1
        jl      got_XOR_mask
        mov     ah,CurLineColor
        je      got_XOR_mask
        not     ah
 got_XOR_mask:
        mov     wBitmapROP,ax                     ; save the masks


;/*
;** decide which set of run routines to use
;*/

        mov     ax,CodeOFFSET bitmap_solid_table
        cmp     LineStyle,LINETYPE_SOLID - 1
        jz      @F
        mov     ax,CodeOFFSET bitmap_styled_table
@@:     mov     anpfnRunRoutines,ax
done_with_mono:
        mov     npfnUnSetup,CodeOFFSET           NullRoutine

        public  NullRoutine
NullRoutine     proc    near
        ret
NullRoutine     endp
bm_polyline_init        endp


;/***************************************************************************
;*
;* PUBLIC ROUTINE  get_bm_info       
;*
;* DESCRIPTION   =  Loads bitmap information from the DDC into local variables.
;*
;*                 Registers Destroyed:  
;*                       AX,BX,CX        
;*                 Registers Preserved:  
;*                       DX,DI,SI,BP,ES  
;*
;* INPUT         = DS:DI => DDC  
;*                 DS:SI => sd  (surface definition)
;* OUTPUT        = DS = first segment of bitmap 
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,Data
        assumes es,nothing

get_bm_info     proc    near
        ddc?    di
        mov     bx,[di].ddc_npsd                 ; get ptr to surface definition
        mov     ax,[bx].sd_cy
        mov     cySurface,ax                      ; height of destination

        mov     ax,[bx].sd_cbScan
        mov     cbScanSize,ax

;/*
;** Check to see if we have a small or a huge bitmap.  If it is huge, then this
;** is a good time to load huge bitmap information.  If it is small, skip this
;** section.
;*/

        xor     ax,ax
        test    [bx].sd_fb,SD_HUGE
        jz      get_bm_info_exit
        mov     ax,[bx].sd_cbFill
        add     ax,[bx].sd_pBits.off
        mov     cbHugeScanWrap,ax
        mov     ax,[bx].sd_cySeg
get_bm_info_exit:
        mov     cScansPerSegment,ax              ; zero for non-huge bitmap
        mov     ax,[bx].sd_pBits.off
        mov     pSurfaceStart.off,ax             ; offset of memory bitmap
        mov     cx,[bx].sd_pBits.sel
        lar     ax,cx
        jz      @F
        cCall   DosGetSeg,<cx>
@@:     mov     ds,cx
        assumes ds,nothing
        mov     pSurfaceStart.sel,cx             ; segment of memory bitmap
        ret
get_bm_info     endp

sEnd    Code

        end
