/*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.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module / File   = EDDGADDB                                       */
/*                                                                    */
/*   Description     = Display Device Driver Bounds Accumulation      */
/*                     Functions:                                     */
/*                     AddRectToBounds,                               */
/*                     AddPointToBounds,                              */
/*                     AddBounds,                                     */
/*                                                                    */
/*   Function        = AddRectToBounds incorporates a rectangle       */
/*                     into given bounds.                             */
/*                     AddPointToBounds incorporates a point          */
/*                     into given bounds.                             */
/*                     AddBounds incorporates given bounds into       */
/*                     current bounds in the DC instance data.        */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
#define INCL_DDICOMFLAGS
#include <eddinclt.h>

#include <eddgextf.h>

/**********************************************************************/
/*                                                                    */
/*   AddRectToBounds incorporates a given rectangle into given bounds */
/* and returns the updated bounds.  UnitsFlag indicates whether the   */
/* co-ords given are in Words or Dwords.  The function will handle    */
/* either type but both co-ord parameters must be in the same type.   */
/*                                                                    */
/* Note: For both the Bounds and Rectangle Co-ords it is assumed that */
/*         Co-ord[0].X <= Co-ord[1].X                                 */
/*         Co-ord[0].Y <= Co-ord[1].Y                                 */
/*                                                                    */
/**********************************************************************/
VOID DRIVERCALL eddg_AddRectToBounds (pDevRect      Bounds,
                                      pDevRect      Rectangle,
                                      USHORT        UnitsFlag)

{
    /******************************************************************/
    /* Update the bounds using the min and max macros.                */
    /* If UnitsFlag is set to indicate Dwords a (pWcsRect) cast       */
    /* is used; otherwise each pointer remains as a (pDevRect)        */
    /******************************************************************/
    if (UnitsFlag & COORDS_ARE_WORDS)
    {
        (*Bounds)[0].X = min( (*Bounds)[0].X, (*Rectangle)[0].X );
        (*Bounds)[0].Y = min( (*Bounds)[0].Y, (*Rectangle)[0].Y );
        (*Bounds)[1].X = max( (*Bounds)[1].X, (*Rectangle)[1].X );
        (*Bounds)[1].Y = max( (*Bounds)[1].Y, (*Rectangle)[1].Y );

    }
    else    /* co-ords are in Dwords                                  */
    {
        (*((pWcsRect)Bounds))[0].X =
                              min( (*((pWcsRect)Bounds))[0].X,
                                   (*((pWcsRect)Rectangle))[0].X );
        (*((pWcsRect)Bounds))[0].Y =
                              min( (*((pWcsRect)Bounds))[0].Y,
                                   (*((pWcsRect)Rectangle))[0].Y );
        (*((pWcsRect)Bounds))[1].X =
                              max( (*((pWcsRect)Bounds))[1].X,
                                   (*((pWcsRect)Rectangle))[1].X );
        (*((pWcsRect)Bounds))[1].Y =
                              max( (*((pWcsRect)Bounds))[1].Y,
                                   (*((pWcsRect)Rectangle))[1].Y );

    }
}


/**********************************************************************/
/*                                                                    */
/*   AddPointToBounds incorporates a given point into given bounds    */
/* and returns the updated bounds.  UnitsFlag indicates whether the   */
/* co-ords given are in Words or Dwords.  The function will handle    */
/* either type but both co-ord parameters must be in the same type.   */
/*                                                                    */
/* Note: For the Bounds it is assumed that                            */
/*         Co-ord[0].X <= Co-ord[1].X                                 */
/*         Co-ord[0].Y <= Co-ord[1].Y                                 */
/*                                                                    */
/**********************************************************************/

VOID DRIVERCALL eddg_AddPointToBounds (pDevRect     Bounds,
                                       pDevPoint    Point,
                                       USHORT       UnitsFlag)

{
    /******************************************************************/
    /* Update the bounds using the min and max macros.                */
    /* If UnitsFlag is set to indicate Dwords then (pWcsPoint)        */
    /* and (pWcsRect) casts are used; otherwise the pointers          */
    /* remain as (pDevPoint) or (pDevRect).                           */
    /******************************************************************/
    if (UnitsFlag & COORDS_ARE_WORDS)
    {
        (*Bounds)[0].X = min( (*Bounds)[0].X, Point->X );
        (*Bounds)[0].Y = min( (*Bounds)[0].Y, Point->Y );
        (*Bounds)[1].X = max( (*Bounds)[1].X, Point->X );
        (*Bounds)[1].Y = max( (*Bounds)[1].Y, Point->Y );

    }
    else    /* co-ords are in Dwords                                  */
    {
        (*((pWcsRect)Bounds))[0].X =
                              min( (*((pWcsRect)Bounds))[0].X,
                                   ((pWcsPoint)Point)->X );
        (*((pWcsRect)Bounds))[0].Y =
                              min( (*((pWcsRect)Bounds))[0].Y,
                                   ((pWcsPoint)Point)->Y );
        (*((pWcsRect)Bounds))[1].X =
                              max( (*((pWcsRect)Bounds))[1].X,
                                   ((pWcsPoint)Point)->X );
        (*((pWcsRect)Bounds))[1].Y =
                              max( (*((pWcsRect)Bounds))[1].Y,
                                   ((pWcsPoint)Point)->Y );

    }

}


/**********************************************************************/
/*                                                                    */
/*   AddBounds incorporates given bounds into current bounds held     */
/* in the DC Instance data.                                           */
/*                                                                    */
/*   StyleFlag indicates which of the bound types are to be updated:  */
/* GPI bounds if the COM_BOUND bit is set;  User bounds if the        */
/* COM_ALT_BOUND bit is set.                                          */
/*                                                                    */
/*   CoordFlag indicates whether the bounds are given in AI, Model,   */
/* Device or World co-ords; these can be in either Words or Dwords.   */
/*                                                                    */
/*   GPI bounds in the DC Instance data are held in Model co-ords in  */
/* Words; User bounds are held in Device co-ords in Words.            */
/*                                                                    */
/* Note: For the Bounds it is assumed that                            */
/*         Co-ord[0].X <= Co-ord[1].X                                 */
/*         Co-ord[0].Y <= Co-ord[1].Y                                 */
/*                                                                    */
/**********************************************************************/

USHORT DRIVERCALL eddg_AddBounds (pDevRect  Bounds,
                                  ULONG     StyleFlag,
                                  USHORT    CoordFlag)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    DevRect         AdjustedBounds;    /* bounds adjusted to Device   */
                                       /* co-ords in Words            */
    WcsRect         wcsAdjustedBounds; /* bounds adjusted to Model    */
                                       /* co-ords in DWords           */
    USHORT          Swap;
    USHORT          Result;            /* function call result        */

    /******************************************************************/
    /* Bounds rectangles in AI coordinates must be re-ordered         */
    /******************************************************************/
    if (CoordFlag & COORDS_ARE_AI)
    {
        Swap           = (*Bounds)[0].Y;
        (*Bounds)[0].Y = (*Bounds)[1].Y;
        (*Bounds)[1].Y = Swap;
    }


    /******************************************************************/
    /* Update current User bounds if the COM_ALT_BOUND bit of         */
    /* StyleFlag is set                                               */
    /******************************************************************/
    if (StyleFlag & COM_ALT_BOUND)
    {
        /**************************************************************/
        /* The given bounds are in World, AI, Model or Device co-ords */
        /* and held in Words or Dwords.  They need to be converted to */
        /* Device co-ords in Words.                                   */
        /**************************************************************/
        Result = eddg_Convert ((PULONG)Bounds,
                               (PULONG)AdjustedBounds,
                               CoordFlag,
                               COORD_DEVICE | COORDS_ARE_WORDS,
                               2,
                               COM_TRANSFORM);

        if (Result != OK)
        {
            return(ERROR_ZERO);
        }

        if (pdc->DCIDefUserBounds == TRUE)
        {
            /**********************************************************/
            /* Set current bounds to new bounds and turn flag off     */
            /**********************************************************/
            pdc->DCIUserBounds[0].X = AdjustedBounds[0].X;
            pdc->DCIUserBounds[0].Y = AdjustedBounds[0].Y;
            pdc->DCIUserBounds[1].X = AdjustedBounds[1].X;
            pdc->DCIUserBounds[1].Y = AdjustedBounds[1].Y;

            pdc->DCIDefUserBounds = FALSE;
        }
        else    /* current User bounds are not default                */
        {
            /**********************************************************/
            /* Update current bounds with new bounds                  */
            /**********************************************************/
            eddg_AddRectToBounds ((pDevRect)pdc->DCIUserBounds,
                                  (pDevRect)AdjustedBounds,
                                  COORDS_ARE_WORDS);
        }

    }

    /******************************************************************/
    /* Update current GPI bounds if the COM_BOUND bit of StyleFlag    */
    /* is set                                                         */
    /******************************************************************/
    if (StyleFlag & COM_BOUND)
    {
        /**************************************************************/
        /* The given bounds are in World, AI, Model or Device co-ords */
        /* and held in Words or Dwords.  They need to be converted to */
        /* Model co-ords in DWords.                                   */
        /**************************************************************/
        Result = eddg_Convert ((PULONG)Bounds,
                               (PULONG)wcsAdjustedBounds,
                               CoordFlag,
                               COORD_MODEL,
                               2,
                               COM_TRANSFORM);

        if (Result != OK)
        {
            return(ERROR_ZERO);
        }

        if (pdc->DCIDefGPIBounds == TRUE)
        {
            /**********************************************************/
            /* Set current bounds to new bounds and turn flag off     */
            /**********************************************************/
            pdc->DCIGPIBounds[0].X = wcsAdjustedBounds[0].X;
            pdc->DCIGPIBounds[0].Y = wcsAdjustedBounds[0].Y;
            pdc->DCIGPIBounds[1].X = wcsAdjustedBounds[1].X;
            pdc->DCIGPIBounds[1].Y = wcsAdjustedBounds[1].Y;

            pdc->DCIDefGPIBounds = FALSE;
        }
        else    /* current GPI bounds are not default                 */
        {
            /**********************************************************/
            /* Update current bounds with new bounds                  */
            /**********************************************************/
            eddg_AddRectToBounds ((PVOID)pdc->DCIGPIBounds,
                                  (PVOID)wcsAdjustedBounds,
                                  0);
        }

    }

    /******************************************************************/
    /* Bounds rectangles in AI coordinates must be set back to right  */
    /* order.                                                         */
    /******************************************************************/
    if (CoordFlag & COORDS_ARE_AI)
    {
        Swap           = (*Bounds)[0].Y;
        (*Bounds)[0].Y = (*Bounds)[1].Y;
        (*Bounds)[1].Y = Swap;
    }

    return(OK);
}
