;*DDK*************************************************************************/
;
; 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 = SLCORR.ASM
;*
;* DESCRIPTIVE NAME = PolyShortLine support routines
;*
;*
;* VERSION      V2.0
;*
;* DATE         08/19/88
;*
;* DESCRIPTION  These are the routines in SHORTLINE.ASM which are common between all
;*              drivers.                                                            
;*              
;*
;* FUNCTIONS    ShortlineCorrelate    
;*              ComputeShortlineBounds
;*                                    
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   05/20/88                     Charles Whitmer [chuckwh] Wrote it.
;*
;*****************************************************************************/

        .386

        OPTION  OLDSTRUCTS

        .xlist

INCL_DDIPATHS           equ     1
INCL_DDIMISC            equ     1
INCL_GRE_LINES          equ     1
INCL_DDICOMFLAGS        equ     1
INCL_GPICORRELATION     equ     1
INCL_GPIPRIMITIVES      equ     1
DINCL_ENABLE            equ     1
DINCL_BITMAP            equ     1

        include pmgre.inc
        include driver.inc
        include polyline.inc
        include assert.mac
        include extern.inc
        include protos.inc

        .list

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

        .DATA

        .CODE

;/***************************************************************************
;*
;* FUNCTION NAME = ShortlineCorrelate 
;*
;* DESCRIPTION   = Performs correlation checking with the given SHORTLINE against 
;*                 the pick window.  We assume that the pick window cannot be
;*                 empty, and that the contents of the SHOTLINE sturcture are
;*                 all unsigned.  We use the fact that the SHOTRLINE is monotonic
;*                 in both X and Y.
;*
;*                 Registers Destroyed:
;*                       BX,CX,DX,ES   
;*                 Registers Preserved:
;*                       SI,DI,BP      
;*
;* INPUT         = DS:SI = DDC 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = AX = 1 if no correlation 
;*                 AX = 2 if correlation    
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ALIGN 4
ShortlineCorrelate      PROC SYSCALL USES edi esi,      psl:DWORD
                        LOCAL   rctl:RECTL

        DebugMsg <ShortlineCorrelate, slcorr, CLIFFL>
ifdef FIREWALLS
        int 3
endif

;/*
;** make sure the pick window is valid in the DDC
;*/

        ASSUME  esi:PTR DDC

        test    [esi].ddc_fb[0],DDC_CORR_INV
        jz      shortline_corr_rect              ; has corr rect in ddc
        call    recalc_correlate_rect   ; get the corr rect

shortline_corr_rect:

;/*
;** copy the pick window to the stack
;*/

        mov     esi,[esi].ddc_prddc              ; ES:SI = prddc (SI != DDC!!!)

        ASSUME  esi:PTR RDDC

        rddc?   esi

        mov     eax,[esi].rddc_rcsCorr.rcl_xLeft
        mov     ebx,[esi].rddc_rcsCorr.rcl_yBottom
        mov     ecx,[esi].rddc_rcsCorr.rcl_xRight
        mov     edx,[esi].rddc_rcsCorr.rcl_yTop

;/*
;** make sure it's unsigned, clip it positive!
;*/

        cmp     eax,ecx
        jb      @F
        xor     eax,eax                           ; this only happens if AX was negative
@@:     cmp     ebx,edx
        jb      @F
        xor     ebx,ebx                           ; this only happens if BX was negative
@@:

;/*
;** make it inclusive, and save it
;*/

        dec     ecx
        dec     edx
        mov     rctl.rcl_xLeft,eax
        mov     rctl.rcl_yBottom,ebx
        mov     rctl.rcl_xRight,ecx
        mov     rctl.rcl_yTop,edx

;/*
;** loop through all SHORTLINEs
;*/

        mov     edi,psl

slc_loop:

;/*
;** find the Y range of the SHORTLINE
;*/

        ASSUME  edi:PTR SHORTLINE

        mov     eax,[edi].sl_slh.slh_ptlStart.ptl_y
        mov     ebx,[edi].sl_slh.slh_ptlStop.ptl_y
        inc     eax                               ; allow last Y to be FFFF
        inc     ebx
        cmp     eax,ebx                           ; move BX towards AX
        jz      slc_next                          ; get rid of empty SHORTLINEs
        sbb     ebx,0
        cmp     ebx,eax
        adc     ebx,-1
        dec     eax                                ; SHORTLINE Y range is [AX,BX]

;/*
;** load the Y range of the pick window
;*/

        mov     ecx,rctl.rcl_yBottom
        mov     edx,rctl.rcl_yTop                ; pick window Y range is [CX,DX]

;/*
;** normalize the ranges with respect to the start of the SHORTLINE
;*/

        sub     ecx,eax
        sub     edx,eax
        sub     ebx,eax
        jae     @F
        neg     ecx
        neg     edx
        xchg    ecx,edx                           ; pick window range is [CX,DX]
        neg     ebx                               ; SHORTLINE range is [0,BX]
@@:

;/*
;** clip the bottom of the pick window to zero, again
;*/

        cmp     ecx,edx
        jbe     @F
        xor     ecx,ecx
@@:

;/*
;** clip the pick window range against the SHORTLINE range
;*/

        cmp     ebx,ecx                           ; check end of SHORTLINE against
        jb      slc_next                          ;   start of pick window
        cmp     ebx,edx                           ; check end of SHORTLINE against
        jb      @F                                ;   end of pick window
        mov     ebx,edx
@@:     mov     esi,ecx                           ; intersection range = [SI,BX]

;/*
;** calculate the X range of the SHORTLINE
;*/

        add     ebx,ebx
        add     ebx,edi                           ; [BX].sl_ax => last scan
        add     esi,esi
        add     esi,edi                           ; [SI].sl_ax => first scan

        ASSUME  esi:PTR SHORTLINE, ebx:PTR SHORTLINE

        mov     eax,[esi].sl_ax        ; AX = first X
        mov     ecx,[ebx].sl_ax
        inc     ecx                               ; allow last X to be FFFF
        cmp     ecx,eax
        ja      @F
        xchg    eax,ecx                           ; X range = [AX,CX]
@@:

;/*
;** compare this to the X range of the pick window
;*/

        cmp     eax,rctl.rcl_xRight
        ja      slc_next
        cmp     ecx,rctl.rcl_xLeft
        jae     slc_hit

;/*
;** go to the next SHORTLINE
;*/

slc_next:

        mov     ecx,[edi].sl_slh.slh_pslhNext
        mov     eax,1
        jecxz   slc_done
        mov     edi,ecx
        jmp     slc_loop
ALIGN 4

;/*
;** return the result
;*/

slc_hit:

        mov     eax,2                             ; we have a hit!

slc_done:
        
        RET

ShortlineCorrelate      ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = ComputeShortlineBounds
;*
;* DESCRIPTION   = Computes a bounding rectangle for a SHORTLINE.  We assume that 
;*                 all coordinates in the SHORTLINE are unsigned.  This must be the
;*                 case since the SHORTLINE is already clipped to the device.
;*
;*                 Registers Destroyed: 
;*                       ES             
;*
;* INPUT         = psl = pointer to the SHORTLINE
;* OUTPUT        = (AX,BX,CX,DX) = RECTS inclusive bounds 
;*
;* RETURN-NORMAL = (AX,BX,CX,DX) = RECTS inclusive bounds
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ALIGN 4
ComputeShortlineBounds  PROC SYSCALL USES edi esi,      psl:DWORD
                        LOCAL   rctl:RECTL


        DebugMsg <ComputeShortlineBounds, slcorr, CLIFFL>
ifdef FIREWALLS
        int 3
endif


;/*
;** initialize the RECTS
;*/

        xor     eax,eax
        mov     rctl.rcl_xRight,eax
        mov     rctl.rcl_yTop,eax
        dec     eax
        mov     rctl.rcl_xLeft,eax
        mov     rctl.rcl_yBottom,eax

;/*
;** loop through all the SHORTLINEs
;*/

        mov     edi,psl

csb_loop:

;/*
;** put the shortline endpoints into (AX,BX) - (CX,DX)
;*/

        ASSUME  edi:PTR SHORTLINE

        mov     ebx,[edi].sl_slh.slh_ptlStart.ptl_y ; BX = first Y
        mov     edx,[edi].sl_slh.slh_ptlStop.ptl_y
        mov     esi,edx
        inc     esi
        inc     ebx                               ; allow a last Y of FFFF
        sub     esi,ebx
        jz      csb_next
        dec     ebx
        sbb     ecx,ecx                           ; CX = FFFF if BX > DX
        xor     esi,ecx
        sub     esi,ecx                           ; SI = |DX - BX|
        add     ecx,ecx
        inc     ecx                               ; CX = sgn(DX - BX)
        sub     edx,ecx                           ; move DX toward BX by one
        add     esi,esi                            ; DX = last Y
        add     esi,edi                           ; [SI].sl_ax => last point
        mov     ecx,[esi].sl_ax                          ; get the last point
        mov     eax,[esi].sl_ax[-4]              ; get the second to last point
        inc     ecx                               ; allow a last X of FFFF
        inc     eax
        cmp     eax,ecx                           ; move the last point towards
        sbb     ecx,0                             ;   the second to last point
        cmp     ecx,eax
        adc     ecx,-1                             ; CX = last X
        mov     eax,[edi].sl_slh.slh_ptlStart.ptl_x ; AX = first X

;/*
;** order the unsigned points to get the inclusive rectangle
;*/

        cmp     eax,ecx
        jb      @F
        xchg    eax,ecx
@@:     cmp     ebx,edx
        jb      @F
        xchg    ebx,edx
@@:

;/*
;** accumulate the points into the rectangle
;*/

        cmp     eax,rctl.rcl_xLeft
        ja      @F
        mov     rctl.rcl_xLeft,eax
@@:     cmp     ebx,rctl.rcl_yBottom
        ja      @F
        mov     rctl.rcl_yBottom,ebx
@@:     cmp     ecx,rctl.rcl_xRight
        jb      @F
        mov     rctl.rcl_xRight,ecx
@@:     cmp     edx,rctl.rcl_yTop
        jb      @F
        mov     rctl.rcl_yTop,edx
@@:

;/*
;** go to the next SHORTLINE
;*/

csb_next:

        mov     ecx,[edi].sl_slh.slh_pslhNext
        jecxz   csb_done
        mov     edi,ecx
        jmp     csb_loop
ALIGN 4

csb_done:

;/*
;** return the rectangle
;*/

        mov     eax,rctl.rcl_xLeft
        mov     ebx,rctl.rcl_yBottom
        mov     ecx,rctl.rcl_xRight
        mov     edx,rctl.rcl_yTop

                        RET

ComputeShortlineBounds  ENDP

        end
