/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark 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.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDLDRAW
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdl_DrawLinesInPath
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                   /* CON3201 */
#define INCL_DOSPROCESS           /* CON3201 */
#define INCL_DOSSEMAPHORES
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPIERRORS
#include <os2.h>
#undef INCL_DOSPROCESS           /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPIERRORS

#define INCL_DDIMISC
#define INCL_DDICOMFLAGS
#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#include <pmddi.h>
#undef INCL_DDIMISC
#undef INCL_DDICOMFLAGS
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_32                    /* CON3201 */

#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL

#include <prdltypt.h>
#include <prdgextf.h>
#include <prdiextf.h>
#include <prdlextf.h>
#include <prdyextf.h>
#include <prdnextf.h>
#include <prdncone.h>

/* extern USHORT     OS2Version; CON3201 - No longer needed */


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdl_DrawLinesInPath                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC           DcH;      Handle to device context               */
/*   PULONG          ArgPath;  Unused parameter                       */
/*   LineRec        *ArgLine;  Pointer to list of lines in path       */
/*   ULONG           ArgCount; Number of lines in path                */
/*   lpDCI           IData;    Instance data                          */
/*   ULONG           FunN;     Function number                        */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function draws the straight lines in a completed path       */
/*   definition. It is called by the engine after a path has been     */
/*   completed                                                        */
/*                                                                    */
/**********************************************************************/
ULONG prdl_DrawLinesInPath ( hanDC     DcH,
                             PULONG    ArgPath,
                             LineRec  *ArgLine,
                             ULONG     ArgCount,
                             lpDCI     DCIData,
                             ULONG     FunN)


{
#define TFUNC "prdl_DrawLIPath"
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    ULONG                Command;      /* Command bits                */
    DevPoint             Start;        /* Start and ...               */
    DevPoint             End;          /*  ... End coordinates of line*/
                                       /* about to be drawn           */
    BYTE                 LineColor;    /* Attributes obtained from the*/
    USHORT               LineMix;      /* line attribute bundle ...   */
    USHORT               LineType;
    PUSHORT              LineMask;
    SHORT                Result;
    pBMListEntry         ListEntry;    /* Pointer to the bitmap list  */
                                       /* entry                       */
    DevRect              Bounds;       /* Bounding rectangle to pass  */
                                       /* to prdg_AddBounds           */
    USHORT               InitialLineMask;
    DevPoint             LastEndPoint;


    /******************************************************************/
    /* If count is zero exit immediately                              */
    /******************************************************************/
    if ( !ArgCount )
        return(OK);

    /******************************************************************/
    /* Get the driver and DCI Data semaphore                          */
    /******************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,8,0A)
#endif
    prdm_EnterDriver(DCIData);

    /******************************************************************/
    /* Get the command bits from the function number                  */
    /******************************************************************/
    Command = FunN & DCIData->CommandMask;

    /******************************************************************/
    /* Do the new framework drawing function - sets DRAWN_INTO flag   */
    /* if COM_DRAW is set. Returns error if not in a suitable state.  */
    /******************************************************************/
    if ( (Result = prdn_CheckDrawingState( (PULONG)&Command,
                                           DCIData ) ) != OK )
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,8A)
#endif
        return( (Result == ERR_PURGE) ? OK : ERROR_ZERO );
    }

    /******************************************************************/
    /* Set the device text only flag to FALSE since we're about to    */
    /* draw into the band.                                            */
    /******************************************************************/
    DCIData->TextOnlyDC = FALSE;

    /******************************************************************/
    /* Reset bit 0 of the style high word to indicate                 */
    /* a figure is not starting (1st pel not drawn)                   */
    /******************************************************************/
    DCIData->StyleNumber &= 0xfffeffff;

    /******************************************************************/
    /* Get the bitmap list entry, colour, mix and style attributes.   */
    /******************************************************************/
    if ( prdl_LineSetUp( &ListEntry,
                         &LineColor,
                         &LineMix,
                         &LineType,
                         (PUSHORT *)&LineMask,
                         DCIData ) != OK )
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,8A)
#endif
        return(ERROR_ZERO);
    }

    /******************************************************************/
    /* If draw and bounding bits are off there is no need to proceed  */
    /* any further.                                                   */
    /******************************************************************/
    if ( (Command & (COM_DRAW | COM_BOUND)) == 0 )
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,8A)
#endif
        return(OK);
    }

    /**************************************************************
     * CON3201 - We are converting to 32 bit so must be           *
     *           running on 2.0 or higher, will always reset      *
     *           the InitialLineMask, as referenced in            *
     *           PD00583                                          *
     *   if (HIBYTE(OS2Version) >= 20)                            *
     *   {                                                        *
     *      InitialLineMask = DCIData->DCILineTypMask;            *
     *   }                                                        *
     **************************************************************/

     InitialLineMask = DCIData->DCILineTypMask;

    /******************************************************************/
    /* Examine each curve in the path which has been given - move to  */
    /* next line record at end of loop.                               */
    /* PD00174 : Ensure we move to the next line if the previous line */
    /* was clipped - this may happen if there is more than one band   */
    /* to the page.                                                   */
    /******************************************************************/
    for (  ; ArgCount-- ; ArgLine = ArgLine->Next )
    {
        /**************************************************************/
        /* If the curve is a straight line then draw it.              */
        /**************************************************************/
        if ( ArgLine->Type == 'L' )
        {
            /**********************************************************/
            /* Set up the start of the next line to draw.             */
            /**********************************************************/
            Start.X = ((PUSHORT)&ArgLine->Start.X)[1];
            Start.Y = ((PUSHORT)&ArgLine->Start.Y)[1];


        /**********************************************************************
         * CON3201 - We are converting to 32 bit so must be                   *
         *           running on 2.0 or higher, will always reset              *
         *           the InitialLineMask, as referenced in                    *
         *           PD00583                                                  *
         *                                                                    *
         *  if ( HIBYTE(OS2Version) >= 20 )                                   *
         *  {                                                                 *
         *     if ( (Start.X != LastEndPoint.X) || (Start.Y != LastEndPoint.Y) )
         *     {                                                              *
         *        *LineMask = InitialLineMask;                                *
         *     }                                                              *
         *  }                                                                 *
         **********************************************************************/

            if ( (Start.X != LastEndPoint.X) || (Start.Y != LastEndPoint.Y) )
            {
               *LineMask = InitialLineMask;
            }

            /**********************************************************/
            /* Set up the end of the next line to draw.               */
            /**********************************************************/
            End.X = ((PUSHORT)&ArgLine->End.X)[1];
            End.Y = ((PUSHORT)&ArgLine->End.Y)[1];

          /********************************************************
           *CON3201 - We are converting to 32 bit so must be      *
           *          running on 2.0 or higher, will always reset *
           *          the InitialLineMask, as referenced in       *
           *          PD00583                                     *
           *if ( HIBYTE(OS2Version) >= 20 )                       *
           *{                                                     *
           *   LastEndPoint.X = End.X;                            *
           *   LastEndPoint.Y = End.Y;                            *
           *}                                                     *
           ********************************************************/

            LastEndPoint.X = End.X;
            LastEndPoint.Y = End.Y;

            /**********************************************************/
            /* Clip the line to the form clip region (provided this   */
            /* is not a Memory DC).                                   */
            /**********************************************************/
            if ( DCIData->DCIDCType != OD_MEMORY )
            {
                if ( prdi_ClipLine ((DevRect  *)
                                       DCIData->DCIPdbInstance->FormClipRegion,
                                    (DevPoint  *)&Start,
                                    (DevPoint  *)&End) != OK )
                {
                    continue;
                }

                if ( prdi_ClipLine ((DevRect  *)
                                       DCIData->DCICurrBand.BDCoords,
                                    (DevPoint  *)&Start,
                                    (DevPoint  *)&End) != OK )
                {
                    continue;
                }

                /******************************************************/
                /* adjust end points for the DC origin                */
                /******************************************************/
                Start.X += ListEntry->XOrigin;
                End.X   += ListEntry->XOrigin;
                Start.Y += ListEntry->YOrigin;
                End.Y   += ListEntry->YOrigin;
            }

            /**********************************************************/
            /* Draw the line using the Bresenham subroutine.          */
            /**********************************************************/
            if ( Command & COM_DRAW )
            {
                (void)Bresenham( ListEntry, Start, End, LineColor,
                                 LineMix, LineType, LineMask, 0 );
            }

            /**********************************************************/
            /* If bounds are required then set up the bounds rectangle*/
            /* from the values which have just been passed to the     */
            /* line drawing algorithm (allowing for the line going in */
            /* a down and/or left direction) and pass these to        */
            /* prdg_AddBounds.                                        */
            /**********************************************************/
            if ( Command & COM_BOUND )
            {
                if ( Start.X > End.X || Start.Y > End.Y )
                {
                    Bounds[0] = End;
                    Bounds[1] = Start;
                }
                else
                {
                    Bounds[0] = Start;
                    Bounds[1] = End;
                }

                (void)prdg_AddBounds( (DevRect  *)Bounds, DCIData );
            }
            /*.. if ( Command & COM_BOUND ) ..........................*/

        }
        /*.. if ( ArgLine->Type == 'L' ) .............................*/

    }
    /*.. for ( ; ArgCount--; (USHORT)ArgLine = ArgLine->Next ) .......*/

    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,8A)
#endif
    return(OK);

}
#undef TFUNC

