/*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 = PRDBIMAG
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdb_ImageData
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

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

#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
#undef INCL_DDICOMFLAGS

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_32                          /* Convert to C/SET2    CON3201       */

#include <prdncone.h>

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

#include <prdbtyp1.h>
#include <prdbextf.h>
#include <prdcextf.h>
#include <prdgextf.h>
#include <prdiextf.h>
#include <prdnextf.h>
#include <prdncone.h>

/******************************************************************************/
/*  Set up access to the default image attributes.                            */
/******************************************************************************/
extern DIMAGEBUNDLE prda_DefImgAts;

/******************************************************************************/
/*  FUNCTION: prdb_ImageData                                                  */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"          */
/*                                                                            */
/*  hanDC  DcH;                                                               */
/*  PBYTE  ArgData;                                                           */
/*  ULONG  ArgNumber;                                                         */
/*  ULONG  ArgRow;                                                            */
/*  lpDCI  DCIData;                                                           */
/*  ULONG  FunN;                                                              */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function draws a row of image data into the currently selected       */
/*  bitmap.  Starting position in the bitmap is the current x position and a y*/
/*  position selected by ArgRow (an offset from the current row).  The image  */
/*  data is a string containing ArgNumber valid bits which are set to         */
/*  foreground colour if they are set and background colour if they are reset.*/
/******************************************************************************/
ULONG EXPENTRY prdb_ImageData( hanDC  DcH,
                               PBYTE  ArgData,
                               ULONG  ArgNumber,
                               ULONG  ArgRow,
                               lpDCI  DCIData,
                               ULONG  FunN )

{
#define TFUNC "prdb_ImageData"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    ULONG                Command;      /* Command part of FunN                */
    DevRect              TrgRow;       /* Device coordinates for target row   */
    DevRect              ClipRow;      /* Clipped target row                  */
    DevRect              SrcRow;       /* Image data to be copied is treated  */
                                       /* as a row from (0,0) to (ArgNumber,0)*/
    DevRect              lcClipReg;    /* Current clip rectangle              */
    USHORT                Swap;         /* Variable for swapping the x coords  */
                                       /* of the row if the direction has been*/
                                       /* reversed by clipping                */
    ULONG                SrcByte;      /* Byte offsets used to access the     */
                                       /* source bitmap (the line)            */
    USHORT               SrcBit;       /* Bit offsets used to access the      */
                                       /* source bitmap                       */
/*  ULONG                PelFgColor;*/ /* Attributes for the target  CON3201  */
    BYTE                 PelFgColor;   /* Attributes for the target  CON3201  */
    USHORT               PelFgMix;     /* bitmap - foreground and             */
/*  ULONG                PelBkColor;*/ /* background colour and      CON3201  */
    BYTE                 PelBkColor;   /* background colour and      CON3201  */
    USHORT               PelBkMix;     /* foreground and background mixes     */
    USHORT               i;            /* Loop control variable               */
    USHORT               j;            /* Loop control variable               */
/*  BitmapListEntry far *ListEntry;       Pointer to a bitmap list entry      */
    BitmapListEntry     *ListEntry;    /* Pointer to a bitmap list ent CON3201*/
    SHORT                Result;
    RECTL                BoundsRectL;  /* Bounds for clipping processing      */

    Command = FunN & DCIData->CommandMask;
    TRACE8("prdbimage", "Command", &Command, 1);
    prdm_ValidatePath;
    prdm_ValidateArea;

    /**************************************************************************/
    /* Do entry processing                                                    */
    /**************************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,7,51)
#endif
    prdm_EnterDriver(DCIData);

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

    /**************************************************************************/
    /*  If there is no bitmap selected for this DC then log and return an     */
    /*  error.                                                                */
    /**************************************************************************/
    if (!(ListEntry = (pBMListEntry)DCIData->DCISelBitmap))
    {
        LOGERR("prdbimage", "No Bitmap", FNULL, 0, PMERR_NO_BITMAP_SELECTED);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D1)
#endif
        return (ERROR_ZERO);
    }

    /**************************************************************************/
    /*  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,7,D1)
#endif
        return((Result==ERR_PURGE) ? OK : ERROR_ZERO);
    }

    /**************************************************************************/
    /*  First-level checks have been completed.  If neither the Draw or Bounds*/
    /*  Bits are on then we can return OK.                                    */
    /**************************************************************************/
    if ((Command & (COM_DRAW | COM_BOUND)) == 0)
    {
        TRACE4("prdbimage", "No Draw/Bounds Bits", &Command, 1);
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D1)
#endif
        return(OK);
    }

    /**************************************************************************/
    /*  Treat ArgNumber == 0 as a special case - just return, no drawing is   */
    /*  done.                                                                 */
    /**************************************************************************/
    if (ArgNumber == 0)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D1)
#endif
        return(OK);
    }

    /**************************************************************************/
    /*  Work out the start and end coordinates in the target bitmap.  ArgRow  */
    /*  is an offset from the current position down the bitmap.  TrgRow is    */
    /*  inclusive at the left and right so it does not matter whether it is   */
    /*  clipped or not.                                                       */
    /**************************************************************************/
    TrgRow[0].X = DCIData->DCICurrPosDev.X;
    TrgRow[0].Y = DCIData->DCICurrPosDev.Y - (USHORT) ArgRow;
    TrgRow[1].Y = TrgRow[0].Y;
    TrgRow[1].X = TrgRow[0].X + (USHORT) ArgNumber - 1;

    /**************************************************************************/
    /*  PD00267 : Pick up the bounding rectangle for the image and pass it to */
    /*  prdi_GetNextClip().                                                   */
    /**************************************************************************/
    BoundsRectL.xLeft   = (ULONG)TrgRow[0].X;
    BoundsRectL.yBottom = (ULONG)TrgRow[0].Y;
    BoundsRectL.xRight  = (ULONG)TrgRow[1].X + 2; /* PD00308...               */
    BoundsRectL.yTop    = (ULONG)TrgRow[1].Y + 2; /* PD00308...               */
    TRACE4("prdbimage", "target row before clip", TrgRow, 2);

    /**************************************************************************/
    /*  If bounds determination required then accumulate bounds               */
    /**************************************************************************/
    if ((Command & COM_BOUND) != 0)
    {
     /* (VOID)prdg_AddBounds((DevRect far *) TrgRow, DCIData); */
        (VOID)prdg_AddBounds((DevRect *) TrgRow, DCIData);         /* CON3201 */
    }

    /**************************************************************************/
    /*  Obtain the foreground colour and mix from the image attributes bundle.*/
    /**************************************************************************/
 /* (BYTE)PelFgColor = prdc_ColorToPelBits(DCIData->DCICurImgAts->ibnd.lColor,*/
    PelFgColor = prdc_ColorToPelBits(DCIData->DCICurImgAts->ibnd.lColor,/*CON3201*/
                                           DCIData, ListEntry->DCTPtr);
    PelFgMix = DCIData->DCICurImgAts->ibnd.usMixMode;
    if (PelFgMix == 0)
    {
        PelFgMix = prda_DefImgAts.ibnd.usMixMode;
    }
    TRACE4("prdbimage", "pelfgcolor", &PelFgColor, 1);
    TRACE4("prdbimage", "pelfgmix",   &PelFgMix, 1);

    /**************************************************************************/
    /*  Obtain the background colour and mix from the image attributes bundle.*/
    /**************************************************************************/
 /* (BYTE)PelBkColor = prdc_ColorToPelBits(DCIData->DCICurImgAts-> */
    PelBkColor = prdc_ColorToPelBits(DCIData->DCICurImgAts->       /* CON3201 */
                                           ibnd.lBackColor, DCIData,
                                           ListEntry->DCTPtr);
    PelBkMix   = DCIData->DCICurImgAts->ibnd.usBackMixMode;
    if (PelBkMix == 0)
    {
        PelBkMix = prda_DefImgAts.ibnd.usBackMixMode;
    }
    TRACE4("prdbimage", "pelbkcolor", &PelBkColor, 1);
    TRACE4("prdbimage", "pelbkmix",   &PelBkMix, 1);
    if ((Command & COM_DRAW) != 0)
    {

        /**********************************************************************/
        /*  COM_DRAW is set so we must do the operation.  PD00267 : Added     */
        /*  &BoundsRectL to the parameter list for prdi_GetNextClip().        */
        /**********************************************************************/
    /*  for (i = 1; prdi_GetNextClip(DCIData, i,(DevRect far*)lcClipReg, */
        for (i = 1; prdi_GetNextClip(DCIData, i,(DevRect *)lcClipReg, /*CON3201*/
                                     &BoundsRectL) == OK; i++)
        {

            /******************************************************************/
            /*  For every valid clip rectangle returned by prdi_GetNextClip.  */
            /*  Start with the unclipped target row...                        */
            /******************************************************************/
            ClipRow[0] = TrgRow[0];
            ClipRow[1] = TrgRow[1];

            /******************************************************************/
            /*  Clip target row against the clip region treating it as a line.*/
            /******************************************************************/
         /* if (prdi_ClipLine((DevRect far*) lcClipReg,              */
         /*                   (DevPoint far*) &(ClipRow[0]),         */
         /*                   (DevPoint far*) &(ClipRow[1])) != OK)  */
            if (prdi_ClipLine((DevRect *) lcClipReg,               /* CON3201 */
                              (DevPoint *) &(ClipRow[0]),          /* CON3201 */
                              (DevPoint *) &(ClipRow[1])) != OK)   /* CON3201 */
            {

                /**************************************************************/
                /*  No intersection so continue to the next clip rectangle.   */
                /**************************************************************/
                TRACE4("prdbimage", "no target intersect", NULL, 0);
                continue;
            }

            /******************************************************************/
            /*  The start and end coordinates of the row may have been        */
            /*  reversed by the clipping so ensure it runs in the correct     */
            /*  direction.                                                    */
            /******************************************************************/
            if (ClipRow[0].X > ClipRow[1].X)
            {
                Swap = ClipRow[0].X;
                ClipRow[0].X = ClipRow[1].X;
                ClipRow[1].X = Swap;
            }

            /******************************************************************/
            /*  There is an intersect - ClipRow has been updated with the     */
            /*  coordinates of the clipped row.  Assuming that the source row */
            /*  has coordinates (0,0) to (n,0) clip it to the corresponding   */
            /*  pels.                                                         */
            /******************************************************************/
            SrcRow[0].X = ClipRow[0].X - TrgRow[0].X;;
            SrcRow[0].Y = 0;
            SrcRow[1].X = ClipRow[1].X - TrgRow[0].X;
            SrcRow[1].Y = 0;
            TRACE4("prdbimage", "clipped source row", SrcRow, 2);

            /******************************************************************/
            /*  Now go through the source pels setting bits in target row     */
            /*  accordingly.                                                  */
            /******************************************************************/
            for (j = SrcRow[0].X; j <= SrcRow[1].X; j++)
            {
                /**************************************************************/
                /*  Work out byte and bit offsets for this pel in the source  */
                /*  bitmap.                                                   */
                /**************************************************************/
                SrcByte = j / 8;
                SrcBit  = j % 8;

                /**************************************************************/
                /*  If the src bit is set then set the target pel to image    */
                /*  foreground color, else set to the image background color. */
                /**************************************************************/
                TRACE4("prdbimage", "set pel X", &j, 1);
                TRACE4("prdbimage", "set pel Y", &(TrgRow[0].Y), 1);
                if ((ArgData[SrcByte] & (0x80 >> SrcBit)) != 0)
                {
                    (VOID)prdb_MixPel(ListEntry, j + TrgRow[0].X, TrgRow[0].Y,
                                      (BYTE)PelFgColor, PelFgMix);
                }
                else
                {
                    (VOID)prdb_MixPel(ListEntry, j + TrgRow[0].X, TrgRow[0].Y,
                                      (BYTE)PelBkColor, PelBkMix);
                }
            }
        }
    }
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,D1)
#endif
    return (OK);
}
#undef TFUNC
