;*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 = plstyle.asm
;*
;* DESCRIPTIVE NAME = Polyline drawing device driver
;*
;*
;* VERSION      V2.0
;*
;* DATE         
;*
;* DESCRIPTION  
;*
;*   Subroutines for drawing styled lines to the display.  These routines  
;*   are called from POLYLINE.ASM (PolyLines) and SHORTLN.ASM              
;*   (PolyShortLine -- thru which all arcs are drawn)                      
;*
;*   Given a set of points, draw a set of polylines connecting adjoining
;*   points.  Depending on whether we are writing to the Display or a bitmap
;*   we initialize as necessary.  Solid and styled lines are handled.
;*   Small (<= 64k bytes) monochrome and color bitmaps and huge monochrome
;*   and color bitmaps are all supported.  A run length slice algorithm is
;*   used to determine the pixels used to draw each line.  The algorithm is
;*   explained later on.  
;*  
;*   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.
;*
;* FUNCTIONS    cProc   setup_poly_frame_styl,
;*              dev_styled_horizontal,
;*              dev_styled_vertical,
;*              dev_styled_diagonal 
;*                                            
;* 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)
;*                                Bob Grudem [bobgru]   Separated from
;*                                pldevsup.asm because the only device
;*                                dependent code was contained in a
;*                                macro (blast_pel_to_screen) which is
;*                                now included via pldevpel.mac.
;*   06/21/88                     Wes Rupel [wesleyr] EGA --> 256-color
;*                                packed pixel ==>  Massive Changes.
;*                                Bob Grudem [bobgru] Implemented the
;*                                "max" metric for line styling.
;*   05/20/88                     Charles Whitmer [chuckwh] Derived all                                                                                           
;*                                the above for the case of clipped
;*                                lines, which Bresenham neglected to
;*                                cover in his paper.
;*****************************************************************************/

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


        public  dev_styled_table

        public  dev_styled_horizontal
        public  dev_styled_vertical
        public  dev_styled_diagonal


sBegin  Code
        assumes cs,Code

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


dev_styled_table        equ                      this word
        dw      dev_styled_horizontal
        dw      dev_styled_vertical
        dw      dev_styled_diagonal
        dw      dev_styled_diagonal


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


;/***************************************************************************
;*
;* FUNCTION NAME = dev_styled_horizontal
;*
;* DESCRIPTION   = Draws a styled horizontal line on the display.
;*
;*         Scheme for speeding up styled line run routines.
;*        
;*         Except in the rare case that someone calls SetStyleRatio the
;*         stylestep will always be 40h (both vertical and horizontal).
;*        
;*         if ((StyleStep != 40h) || (CX is small))
;*         {
;*            use_old_code       /* i.e. the currently existing code */
;*         }
;*         else
;*         {
;*            while ( CX > 0 )
;*            {
;*               Compute number of pels     /* initial bit in style mask represents */
;*               (cPels) to do from         /*   4 - StyleError/40h  pels   */
;*               current mask bit.          /* Note that StyleError/40h can be done */
;*                                          /* as ROL AL,2     */
;*               while(next mask bit is the same as the current one)
;*                   add 4 to cPels
;*               if (these bits were "1" bits)
;*                   Draw min(cPels,CX)
;*               else
;*                   skip ahead to next next pel to draw,
;*                   or end of run, whichever comes first
;*            )
;*            Save proper final state in StyleMask and StyleError frame variables.
;*         }
;*
;*
;*                 Registers Destroyed:
;*                       AX,CX,DX,SI
;*                 Registers Preserved:
;*                       DI,BP
;*        
;*                 DI = Y coordinate
;*                 CX = number of pels to draw
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = BX = last X coord drawn to 
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing

dev_styled_horizontal    proc                     near
        assert  cx,A,0

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


        mov     si,bx
        xor     bh,bh
        mov     bl,bActiveStyleCounter           ; BL = style error
        mov     dh,bActiveStyleMask              ; DH = style mask

bsh_loop:

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


        or      dh,dh
        jns     @F
        blast_pel_to_screen                      ; SI = x, DI = y
@@:

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


        mov     bh,0FFh
        add     bx,wStyleStepHorz                ; add to StyleCounter
        jnc     @F
        rol     dh,1                             ; ROL mask 1 bit if StyleCounter spilled over
@@:

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


        inc     si                               ; increment the X coordinate

        loop    bsh_loop

;/*
;** set/save exit state: everything advances one less than # total pels output
;*/


        dec     si
        sub     bl,byte ptr wStyleStepHorz       ; set StyleCounter back one step
        or      bh,bh
        jnz     @F
        ror     dh,1                             ; adjust mask accordingly
@@:
        mov     bActiveStyleCounter,bl
        mov     bActiveStyleMask,dh
        mov     bx,si
        ret
dev_styled_horizontal    endp


;/***************************************************************************
;*
;* FUNCTION NAME = dev_styled_vertical
;*
;* DESCRIPTION   = Draws a stlyed vertical line on the display. 
;*
;*                 Registers Destroyed:
;*                       AX,CX,DX,SI
;*                 Registers Preserved:
;*                       BX,BP
;*
;*                 DI = Y coordinate
;*                 CX = number of pels to draw
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = DI = last Y coord drawn to 
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing

dev_styled_vertical    proc    near
        assert  cx,A,0

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


        mov     si,bx
        mov     bl,bActiveStyleCounter           ; BL = style "error"
        mov     dh,bActiveStyleMask              ; DH = style mask
dsv_loop:

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


        or      dh,dh
        jns     @F
        blast_pel_to_screen                      ; SI = x, DI = y
@@:

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


        mov     bh,0FFh
        add     bx,wStyleStepVert                ; add to StyleCounter
        jnc     @F
        rol     dh,1                             ; ROL mask 1 bit if StyleCounter spilled over
@@:

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


        add     di,cbScanAddressDelta            ; deltaY == (+/-) 1
        loop    dsv_loop

;/*
;** set/save exit state: everything advances one less than # total pels output
;*/


        sub     di,cbScanAddressDelta
        sub     bl,byte ptr wStyleStepVert       ; set StyleCounter back one step
        or      bh,bh
        jnz     @F
        ror     dh,1                             ; adjust mask accordingly
@@:
        mov     bActiveStyleCounter,bl
        mov     bActiveStyleMask,dh
        mov     bx,si
        ret
dev_styled_vertical    endp


;/***************************************************************************
;*
;* FUNCTION NAME = dev_styled_diagonal
;*
;* DESCRIPTION   = Draws a stlyed diagonal line on the EGA. 
;*
;*                 Registers Destroyed:
;*                       AX,CX,DX,SI
;*                 Registers Preserved:
;*                       BP
;*
;* INPUT         = BX = X coordinate
;*                 DI = Y coordinate
;*                 CX = number of pels to draw
;* OUTPUT        = BX = last X coord drawn to
;*                 DI = last Y coord drawn to
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

        assumes ds,nothing
        assumes es,nothing


dev_styled_diagonal    proc    near
        assert  cx,A,0

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


        mov     si,bx
        mov     bl,bActiveStyleCounter           ; BL = style "error"
        mov     dh,bActiveStyleMask              ; DH = style mask

dsd_loop:                                        ; output a pel if the style 
                                                 ; mask's high bit is "1" 
        or      dh,dh
        jns     @F
        blast_pel_to_screen                      ; SI = x, DI = y
@@:

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


        mov     bh,0FFh
        add     bx,wStyleStepDiag                ; add to StyleCounter
        jnc     @F
        rol     dh,1                             ; ROL mask 1 bit if StyleCounter 
@@:                                              ; spilled over 

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


        inc     si
        add     di,cbScanAddressDelta            ; move to the next pel
        loop    dsd_loop

;/*
;** set/save exit state: everything advances one less than # total pels output
;*/


        dec     si
        sub     di,cbScanAddressDelta
        sub     bl,byte ptr wStyleStepDiag       ; set StyleCounter back one step
        or      bh,bh
        jnz     @F
        ror     dh,1
@@:
        mov     bActiveStyleCounter,bl
        mov     bActiveStyleMask,dh
        mov     bx,si
        ret
dev_styled_diagonal    endp

sEnd    Code
        end
