/*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 = PRDGACCB
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS  prdg_AccumulateBounds
 *            prdg_GetBoundsData
 *            prdg_ResetBounds
 *            prdt_GetBoundingRect
 *
 * 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_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPIERRORS
#undef INCL_DOSPROCESS            /* CON3201 */

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

#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_SYS
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef NO_SYS

#include <prdgextf.h>
#include <prdyextf.h>


/**********************************************************************/
/* Set up access to the engine handlers for GetBoundsData and         */
/* ResetBounds so we can pass calls onto them.                        */
/**********************************************************************/
extern PFNL   da_GetBoundsData;
extern PFNL   da_ResetBounds;

#define TFUNC "prdg_AccBounds"
/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdg_AccumulateBounds                                  */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC          DcH;                                              */
/*   WcsRect      * ArgBoundsRect;                                    */
/*   lpDCI          DCIData;                                          */
/*   ULONG          FunN;                                             */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function converts the bounds rectangle passed to it (with   */
/*   coordinates stored as device coordinates in Dwords) into a       */
/*   bounds rectangle with coordinates stored as Words and passes     */
/*   this rectangle to prdg_AddBounds to update the current overall   */
/*   bounds.  This allows the engine to add to the current overall    */
/*   bounds rectangle.                                                */
/*                                                                    */
/**********************************************************************/
ULONG EXPENTRY prdg_AccumulateBounds ( hanDC      DcH,
                                       WcsRect  * ArgBoundsRect,
                                       lpDCI      DCIData,
                                       ULONG      FunN)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    DevRect   BoundsRect;       /* The bounds rectangle in word format*/
    ULONG     Command;          /* command bits from FunN             */

    /******************************************************************/
    /* Trace the input parameters                                     */
    /******************************************************************/
    TRACE8("prdgAccumBounds", "BoundsRect", ArgBoundsRect, 4);
    TRACE8("prdgAccumBounds", "DcH", &DcH, 1);
    TRACE8("prdgAccumBounds", "FunN", &FunN, 1);
    TRACE8("prdgAccumBounds", "DCIData", &DCIData, 1);

    Command = GetCommand(DCIData);
    prdm_EnterDriver(DCIData);
    /******************************************************************/
    /* if COM_TRANSFORM is clear then we have been given model        */
    /* coordinates. handle these in this function. If COM_TRANSFORM   */
    /* is set then handle the bounds in prdg_addbounds                */
    /******************************************************************/
    if ( !(Command & COM_TRANSFORM) )
    {
        if (DCIData->DCIBounds[0].X > (*ArgBoundsRect)[0].X)
            DCIData->DCIBounds[0].X = (*ArgBoundsRect)[0].X;

        if (DCIData->DCIBounds[0].Y > (*ArgBoundsRect)[0].Y)
            DCIData->DCIBounds[0].Y = (*ArgBoundsRect)[0].Y;

        if (DCIData->DCIBounds[1].X < (*ArgBoundsRect)[1].X)
            DCIData->DCIBounds[1].X = (*ArgBoundsRect)[1].X;

        if (DCIData->DCIBounds[1].Y < (*ArgBoundsRect)[1].Y)
            DCIData->DCIBounds[1].Y = (*ArgBoundsRect)[1].Y;

    }
    else
    /******************************************************************/
    /* The given bounding rectangle is in device coordinates, but     */
    /* stored as Dword's so change the bounding rectangle to a DevRect*/
    /* to call the function prdg_AddBounds.                           */
    /******************************************************************/
    {
        BoundsRect[0].X = (USHORT)(*ArgBoundsRect)[0].X;
        BoundsRect[0].Y = (USHORT)(*ArgBoundsRect)[0].Y;
        BoundsRect[1].X = (USHORT)(*ArgBoundsRect)[1].X;
        BoundsRect[1].Y = (USHORT)(*ArgBoundsRect)[1].Y;

        /**************************************************************/
        /* prdg_AddBounds accumulates the bounds                      */
        /**************************************************************/
        (void) prdg_AddBounds ((DevRect  *)BoundsRect, DCIData);
    }

    TRACE4("prdgAccumBounds", "Exit", FNULL, 0);

    prdm_LeaveDriver(DCIData);
    return (OK);
}


#undef TFUNC
#define TFUNC "prdg_GetBoundsData"
/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdg_GetBoundsData                                     */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC          DcH;                                              */
/*   ULONG          ArgStyle;                                         */
/*   WcsRect      * ArgBoundsRect;                                    */
/*   lpDCI          DCIData;                                          */
/*   ULONG          FunN;                                             */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function converts the current overall bounds (from the DC   */
/*   Instance data) into Dword format and returns them in             */
/*   ArgBoundsRect.  It also handles default bounds if these are      */
/*   currently selected.                                              */
/*                                                                    */
/**********************************************************************/
ULONG EXPENTRY prdg_GetBoundsData (  hanDC      DcH,
                                     ULONG      ArgStyle,
                                     WcsRect  * ArgBoundsRect,
                                     lpDCI      DCIData,
                                     ULONG      FunN)

{
    /******************************************************************/
    /* Trace the input parameters                                     */
    /******************************************************************/
    TRACE8("prdgGetBounds", "BoundsRect", &ArgBoundsRect, 1);
    TRACE8("prdgGetBounds", "Style", &ArgStyle, 1);
    TRACE8("prdgGetBounds", "DcH", &DcH, 1);
    TRACE8("prdgGetBounds", "FunN", &FunN, 1);
    TRACE8("prdgGetBounds", "DCIData", &DCIData, 1);

    prdm_EnterDriver(DCIData);
    /******************************************************************/
    /*      return current bounds from the DC Instance data.          */
    /******************************************************************/
    (*ArgBoundsRect)[0].X = DCIData->DCIBounds[0].X;
    (*ArgBoundsRect)[0].Y = DCIData->DCIBounds[0].Y;
    (*ArgBoundsRect)[1].X = DCIData->DCIBounds[1].X;
    (*ArgBoundsRect)[1].Y = DCIData->DCIBounds[1].Y;

    TRACE4("prdgGetBounds", "Bounds", ArgBoundsRect, 4);
    TRACE4("prdgGetBounds", "Exit", FNULL, 0);

    prdm_LeaveDriver(DCIData);
    return (OK);
}


#undef TFUNC
#define TFUNC "prdg_ResetBounds"
/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdg_ResetBounds                                       */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   hanDC          DcH;                                              */
/*   ULONG          ArgFlags;                                         */
/*   lpDCI          DCIData;                                          */
/*   ULONG          FunN;                                             */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function resets the current overall bounds by setting the   */
/*   flag for default bounds to true.                                 */
/*                                                                    */
/**********************************************************************/
ULONG EXPENTRY prdg_ResetBounds ( hanDC          DcH,
                                  ULONG          ArgFlags,
                                  lpDCI          DCIData,
                                  ULONG          FunN)

{
    /******************************************************************/
    /* Trace the input parameters                                     */
    /******************************************************************/
    TRACE8("prdgResetBounds", "DcH", &DcH, 1);
    TRACE8("prdgResetBounds", "FunN", &FunN, 1);
    TRACE8("prdgResetBounds", "Flags", &ArgFlags, 1);
    TRACE8("prdgResetBounds", "DCIData", &DCIData, 1);

    prdm_EnterDriver(DCIData);

    TRACE4("prdgResetBounds", "GPI Bounds", NULL, 0);
    /**************************************************************/
    /* set the default values. The bounds rectangle is inverted,  */
    /* ie. the bottom left croner is the maximum allowed          */
    /* positive number, the top right corner is the maximum       */
    /* negative number. This ensures that the first call to       */
    /* accumulate bounds will always be a bigger rectangle        */
    /**************************************************************/
    DCIData->DCIBounds[0].X = 0x07FFFFFFL;
    DCIData->DCIBounds[0].Y = 0x07FFFFFFL;
    DCIData->DCIBounds[1].X = 0xf8000000L;
    DCIData->DCIBounds[1].Y = 0xf8000000L;

    TRACE4("prdgResetBounds", "Exit", FNULL, 0);

    prdm_LeaveDriver(DCIData);
    return (OK);
}


#undef TFUNC


/******************************************************************************/
/*  FUNCTION: prdg_GetBoundingRect                                    PD00073 */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  FOURPOINTL      box                                                       */
/*  DevRect         rect                                                      */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/* This function returns the bounding rectangle of the four points            */
/* passed in.                                                                 */
/*                                                                            */
/*          ÚÄÄÄÄÄÄp2ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄrect[1]                                   */
/*          ³                         ³                                       */
/*          ³                         ³                                       */
/*          ³                         p3                                      */
/*          p1                        ³                                       */
/*          ³                         ³                                       */
/*          ³                         ³                                       */
/*        rect[0]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄp4ÄÄÄÄÄÙ                                       */
/*                                                                            */
/******************************************************************************/
VOID prdg_GetBoundingRect( PFOURPOINTL    box,
                           DevRect      * pRect)

{
   (*pRect)[0].X = (SHORT) min( ( min(box->BottomLeft.x,
                                  box->TopLeft.x) ),
                                ( min(box->BottomRight.x,
                                  box->TopRight.x ) ) );

   (*pRect)[1].X = (SHORT) max( ( max(box->BottomLeft.x,
                                  box->TopLeft.x) ),
                                ( max(box->BottomRight.x,
                                  box->TopRight.x ) ) );

   (*pRect)[0].Y = (SHORT) min( ( min(box->BottomLeft.y,
                                  box->TopLeft.y) ),
                                ( min(box->BottomRight.y,
                                  box->TopRight.y ) ) );

   (*pRect)[1].Y = (SHORT) max( ( max(box->BottomLeft.y,
                                  box->TopLeft.y) ),
                                ( max(box->BottomRight.y,
                                  box->TopRight.y ) ) );

}
