/*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 = PRD42SR2
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prda_ConvertOld42XXMatch
 *             prda_GetNewMatchNumber
 *             prdp_Print360by360
 *             prdp_Print360by180
 *             prdp_PrintRasterPass
 *
 * 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
#define INCL_SPL

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

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

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

#include <prdconse.h>
#include <prddcone.h>
#include <prdncone.h>
#include <prdpcone.h>
#include <prdtcone.h>

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

#include <prdaextf.h>
#include <prdgextf.h>
#include <prdnextf.h>
#include <prduextf.h>
#include <prdpextf.h>

extern USHORT              MatchNoProI[];
extern USHORT              MatchNoProXL[];
extern USHORT              MatchNoProII[];
extern USHORT              MatchNoProIII[];
extern USHORT              MatchNoPro24[];
/******************************************************************************/
/*  FUNCTION: prda_ConvertOld42XXMatch                                                  */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFATTRS  LogFont;         Details of font to be matched                   */
/*  lpDCI    DCIData;         Pointer to DC Instance Data                     */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function tries to convert an old 42XX match number into the correct  */
/*  current match number.  The conversion will only take place for code pages */
/*  437 and 850.  After this all match numbers depends on the order it was    */
/*  installed.                                                                */
/******************************************************************************/
/* CON3201
VOID prda_ConvertOld42XXMatch (LogFont, DCIData)

PFATTRS     LogFont;
lpDCI       DCIData;
                     */
VOID prda_ConvertOld42XXMatch (PFATTRS     LogFont,
                               lpDCI       DCIData)

{
   ULONG  ulAbsMatch;              /* absolute value of the match number */
   USHORT DevAttr;                 /* device attributes of font */
   USHORT FtIndex;                 /* font index */
   USHORT MaxNumber;               /* maximun number of the match numbers */
   USHORT NumberOfFonts;           /* number of fonts */
   USHORT FontNumber;              /* The value of the current font index */
   ULONG  NumberOfFontsSoFar;      /* Number of font match number found */
   BYTE   i;                       /* Counter */
   BYTE   j;
   USHORT AttrFlag;
   USHORT DownLoad;                /* Set if download codepage */
   USHORT NumberOfCodePages;
   BOOL Found[9];
   USHORT IndexValue;

   if (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_I)
   {
      MaxNumber = 217;
      NumberOfFonts = 5;
      NumberOfCodePages = 8;
      prda_GetNewMatchNumber(MaxNumber, NumberOfFonts, 0, LogFont,
                             NumberOfCodePages, DCIData);
   }

   if (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_XL)
   {
      MaxNumber = 345;
      NumberOfFonts = 7;
      NumberOfCodePages = 8;
      prda_GetNewMatchNumber(MaxNumber, NumberOfFonts, 1, LogFont,
                             NumberOfCodePages, DCIData);
   }

   if ( (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_II) ||
         (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_II_XL) )
   {
      MaxNumber = 457;
      NumberOfFonts = 10;
      NumberOfCodePages = 8;
      prda_GetNewMatchNumber(MaxNumber, NumberOfFonts, 2, LogFont,
                             NumberOfCodePages, DCIData);
   }

   if ( (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_III) ||
         (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_III_XL) )
   {
      MaxNumber = 593;
      NumberOfFonts = 13;
      NumberOfCodePages = 8;
      prda_GetNewMatchNumber(MaxNumber, NumberOfFonts, 3, LogFont,
                             NumberOfCodePages, DCIData);
   }

   if ( (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_X24) ||
         (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_XL24) )
   {
      MaxNumber = 559;
      NumberOfFonts = 7;
      NumberOfCodePages = 9;
      prda_GetNewMatchNumber(MaxNumber, NumberOfFonts, 4, LogFont,
                             NumberOfCodePages, DCIData);
   }

   if ( (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_X24E) ||
         (DCIData->DCIPdbInstance->PrinterType == IBM_PRO_PRINTER_XL24E) )
   {
      /*********************************************************************/
      /* Same as described in prda_GetNewMatchNumber except the fonts in CP*/
      /* 850 are resident not downloaded, so the font index just keeps     */
      /* decrementing as usual.                                            */
      /*********************************************************************/

      ulAbsMatch = abs(LogFont->lMatch);
      if ( ulAbsMatch < 559 )
      {
         DownLoad = 0;
         if (ulAbsMatch > 62)
         {
            while (ulAbsMatch > 62)
            {
               ulAbsMatch -= 62;
            }
            DownLoad = 1;
            for ( j = 0; j < 9; j++)
            {
               Found[j] = FALSE;
            }
            for ( j = 2; j < 9; j++)
            {
               for ( i = 1; i < NO_OF_ADDABLE_CPS + 1; i++ )
               {
                  if (DCIData->DCIPdbInstance->PrinterData->CPPathList[i] != NULL)
                  {
                     Found[j] = TRUE;
                  }
               }
            }
         }
         FontNumber = 0;
         NumberOfFontsSoFar = 0;
         while (FontNumber < 7)
         {
            AttrFlag = MatchNoPro24[FontNumber];
            for (i = 0; i < 11; i++)
            {
               if ( (AttrFlag >> i) & (0x0001) )
               {
                  NumberOfFontsSoFar++;
                  if (NumberOfFontsSoFar == ulAbsMatch)
                  {
                     break;
                  }
               }
            }
            if (NumberOfFontsSoFar == ulAbsMatch)
               break;
            else
               FontNumber++;
         }
         switch (i)
         {
            case 0 :
               DevAttr = FATT_NONE;
               break;
            case 1 :
               DevAttr = FATT_DOUBLE_WIDE;
               break;
            case 2 :
               DevAttr = FATT_DOUBLE_HIGH;
               break;
            case 3 :
               DevAttr = FATT_BOTH;
               break;
            case 4 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
            case 5 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
               break;
            case 6 :
               DevAttr = FATT_DOUBLE_WIDE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
            case 7 :
               DevAttr = FATT_DOUBLE_HIGH;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
            case 8 :
               DevAttr = FATT_BOTH;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
            case 9 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
            case 10 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
         }
         if (DownLoad == 1)
         {
            ulAbsMatch = abs(LogFont->lMatch);
            IndexValue = 0;
            while (ulAbsMatch > 62)
            {
                ulAbsMatch -= 62;
                IndexValue++;
            }
            if (IndexValue == 1)
            {
               FontNumber += 7;
               DownLoad = 0;
            }
            else
            {
               for ( j = (BYTE)IndexValue; j < 9; j++)
               {
                  if (Found[j] == TRUE)
                  {
                     switch (j)
                     {
                        case 2 :
                           FontNumber += 512;
                           break;
                        case 3 :
                           FontNumber += 768;
                           break;
                        case 4 :
                           FontNumber += 1024;
                           break;
                        case 5 :
                           FontNumber += 1280;
                           break;
                        case 6 :
                           FontNumber += 1536;
                           break;
                        case 7 :
                           FontNumber += 1792;
                           break;
                        case 8 :
                           FontNumber += 2048;
                           break;
                     }
                  }
                  if (FontNumber > 256)
                  {
                     if (ulAbsMatch == 62)
                     {
                        Found[j] = FALSE;
                     }
                     break;
                  }
               }
               if (FontNumber < 256)
               {
                  return;
               }
            }
         }
         LogFont->lMatch = ( 0xFF000000 | (DownLoad << 14) |
                             (FontNumber << 2) | DevAttr );
      }
   }
   if ( (DCIData->DCIPdbInstance->PrinterType == IBM_4224_COLOR) ||
         (DCIData->DCIPdbInstance->PrinterType == IBM_4224_MONO) )
   {
      /********************************************************************/
      /* 4224 printers support OCR-A and OCR-B in the match numbers -133  */
      /* and -134 so special case it.                                     */
      /********************************************************************/

      ulAbsMatch = abs(LogFont->lMatch);
      if ( (ulAbsMatch < 243) && (ulAbsMatch != 133) &&
           (ulAbsMatch != 134) )
      {
         DownLoad = 0;
         if (ulAbsMatch > 134)
         {
            ulAbsMatch -= 134;
            DownLoad = 1;
         }
         switch ( ((BYTE)(ulAbsMatch % 6)) )
         {
            case 0 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               LogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
               break;
            case 1 :
               DevAttr = FATT_NONE;
               break;
            case 2 :
               DevAttr = FATT_DOUBLE_WIDE;
               break;
            case 3 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
            case 4 :
               DevAttr = FATT_NONE;
               LogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
               break;
            case 5 :
               DevAttr = FATT_DOUBLE_WIDE;
               LogFont->fsSelection |= FATTR_SEL_BOLD;
               break;
         }
         ulAbsMatch -= 1;
         FtIndex = (USHORT) (ulAbsMatch / 6);

         /*******************************************************************/
         /* 4224 printers support italic on all fonts.  The old match       */
         /* numbers treated them as a seperate font, but the new supports it*/
         /* as an attribute.  Therefore the correct number is subtracted and*/
         /* the FATTR is set.                                               */
         /*******************************************************************/

         if ( (FtIndex > 8) && (FtIndex < 18) )
         {
            FtIndex -= 9;
            LogFont->fsSelection |= FATTR_SEL_ITALIC;
         }
         if ( (FtIndex > 19) && (FtIndex < 22) )
         {
            FtIndex -= 2;
            LogFont->fsSelection |= FATTR_SEL_ITALIC;
         }
         if (DownLoad == 1)
         {
            FtIndex += 11;
         }
         LogFont->lMatch = ( 0xFF000000 |
                             (FtIndex << 2) | DevAttr );
      }
      if (ulAbsMatch == 133)
      {
         LogFont->lMatch = ( 0xFF000000 | (0x0014 << 2) );
      }
      if (ulAbsMatch == 134)
      {
         LogFont->lMatch = ( 0xFF000000 | (0x0015 << 2) );
      }
   }
}
/******************************************************************************/
/*  FUNCTION: prda_GetNewMatchNumber                                          */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  USHORT   MaxNumber;       Maximum number of font match numbers available  */
/*  USHORT   NumberOfFonts;   Number of fonts available                       */
/*  USHORT  *MatchTable[]; Pointer to the match table                      */
/*  PFATTRS  LogFont;         Details of font to be matched                   */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function tries to convert an old 42XX match number into the correct  */
/*  current match number.  The conversion will only take place for code pages */
/*  437 and 850.  After this all match numbers depends on the order it was    */
/*  installed.                                                                */
/******************************************************************************/
/* CON3201
VOID prda_GetNewMatchNumber (MaxNumber, NumberOfFonts, MatchTable,
                                        LogFont, NoOfCodePages, DCIData)

USHORT      MaxNumber;
USHORT      NumberOfFonts;
USHORT      MatchTable;
PFATTRS     LogFont;
USHORT      NoOfCodePages;
lpDCI       DCIData;
                      */
VOID prda_GetNewMatchNumber (USHORT      MaxNumber,
                             USHORT      NumberOfFonts,
                             USHORT      MatchTable,
                             PFATTRS     LogFont,
                             USHORT      NoOfCodePages,
                             lpDCI       DCIData)

{
   ULONG  ulAbsMatch;              /* absolute value of the match number */
   USHORT DevAttr;                 /* device attributes of font */
   USHORT FtIndex;                 /* font index */
   USHORT FontNumber;              /* The value of the current font index */
   ULONG  NumberOfFontsSoFar;      /* Number of font match number found */
   BYTE   i;                       /* Counter */
   BYTE   j;
   USHORT AttrFlag;
   USHORT DownLoad;
   BOOL Found[9];
   USHORT IndexValue;
   USHORT FontsPerCP;

   /*************************************************************************/
   /* If the font match number is for a font in code page 850 then set the  */
   /* download flag to one.  Then loop through the values in the table until*/
   /* the correct font is found.  Each bit in the ushort corresponds to a   */
   /* device engine attribute combination.  The switch statement is used to */
   /* get the correct one.                                                  */
   /*************************************************************************/
   ulAbsMatch = abs(LogFont->lMatch);
   if ( ulAbsMatch < MaxNumber )
   {
      DownLoad = 0;
      FontsPerCP = ((MaxNumber - 1) / NoOfCodePages);
      if (ulAbsMatch > FontsPerCP)
      {
         while (ulAbsMatch > FontsPerCP)
         {
            ulAbsMatch -= FontsPerCP;
         }
         DownLoad = 1;
         for ( j = 0; j < 9; j++)
         {
            Found[j] = FALSE;
         }
         for ( i = 1; i < NO_OF_ADDABLE_CPS + 1; i++ )
         {
            if (DCIData->DCIPdbInstance->PrinterData->CPPathList[i] != NULL)
            {
               Found[i+1] = TRUE;
            }
         }
      }
      FontNumber = 0;
      NumberOfFontsSoFar = 0;
      while (FontNumber < NumberOfFonts)
      {
         switch (MatchTable)
         {
            case 0 :
               AttrFlag = MatchNoProI[FontNumber];
               break;
            case 1 :
               AttrFlag = MatchNoProXL[FontNumber];
               break;
            case 2 :
               AttrFlag = MatchNoProII[FontNumber];
               break;
            case 3 :
               AttrFlag = MatchNoProIII[FontNumber];
               break;
            case 4 :
               AttrFlag = MatchNoPro24[FontNumber];
         }
         for (i = 0; i < 11; i++)
         {
            if ( (AttrFlag >> i) & (0x0001) )
            {
               NumberOfFontsSoFar++;
               if (NumberOfFontsSoFar == ulAbsMatch)
               {
                  break;
               }
            }
         }
         if (NumberOfFontsSoFar == ulAbsMatch)
            break;
         else
            FontNumber++;
      }
      switch (i)
      {
         case 0 :
            DevAttr = FATT_NONE;
            break;
         case 1 :
            DevAttr = FATT_DOUBLE_WIDE;
            break;
         case 2 :
            DevAttr = FATT_DOUBLE_HIGH;
            break;
         case 3 :
            DevAttr = FATT_BOTH;
            break;
         case 4 :
            DevAttr = FATT_NONE;
            LogFont->fsSelection |= FATTR_SEL_BOLD;
            break;
         case 5 :
            DevAttr = FATT_NONE;
            LogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
            break;
         case 6 :
            DevAttr = FATT_DOUBLE_WIDE;
            LogFont->fsSelection |= FATTR_SEL_BOLD;
            break;
         case 7 :
            DevAttr = FATT_DOUBLE_HIGH;
            LogFont->fsSelection |= FATTR_SEL_BOLD;
            break;
         case 8 :
            DevAttr = FATT_BOTH;
            LogFont->fsSelection |= FATTR_SEL_BOLD;
            break;
         case 9 :
            DevAttr = FATT_NONE;
            LogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
            LogFont->fsSelection |= FATTR_SEL_BOLD;
            break;
         case 10 :
            DevAttr = FATT_NONE;
            LogFont->fsSelection |= FATTR_SEL_BOLD;
            break;
      }
      /*********************************************************************/
      /* All the download codepage fonts have an index of 256 or greater   */
      /* also the download bit is set in the match number.                 */
      /*********************************************************************/

      if (DownLoad == 1)
      {
         ulAbsMatch = abs(LogFont->lMatch);
         IndexValue = 0;
         while (ulAbsMatch > FontsPerCP)
         {
            ulAbsMatch -= FontsPerCP;
            IndexValue++;
         }
         if (IndexValue == 1)
         {
            FontNumber += 256;
         }
         else
         {
            for ( j = (BYTE)IndexValue; j < 9; j++)
            {
               if (Found[j] == TRUE)
               {
                  switch (j)
                  {
                     case 2 :
                        FontNumber += 512;
                        break;
                     case 3 :
                        FontNumber += 768;
                        break;
                     case 4 :
                        FontNumber += 1024;
                        break;
                     case 5 :
                        FontNumber += 1280;
                        break;
                     case 6 :
                        FontNumber += 1536;
                        break;
                     case 7 :
                        FontNumber += 1792;
                        break;
                     case 8 :
                        FontNumber += 2048;
                        break;
                  }
               }
               if (FontNumber > 256)
               {
                  if (ulAbsMatch == FontsPerCP)
                  {
                     Found[j] = FALSE;
                  }
                  break;
               }
            }
            if (FontNumber < 256)
            {
               return;
            }
         }
      }
      LogFont->lMatch = ( 0xFF000000 | (DownLoad << 14) |
                          (FontNumber << 2) | DevAttr );
   }
}

/******************************************************************************/
/*  FUNCTION: prdp_Print360by360                                              */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function outputs two 24 bit deep 360x360 scanline passes to the      */
/*  printer by doing every other bit of every other byte for four passes to   */
/*  produce a simulated 360x360.                                              */
/******************************************************************************/
/*CON3201
USHORT prdp_Print360by360 (pDDT, PassBuffer, BufferSize,
                                      OutputBuffer, OutputBuffer2,
                                      CommandBuffer, pCommandIndex, CommandSize,
                                      NewPosX, pHeadYPos, DCIData, RasterLength,
                                      InputBuffer)

lpDDTType   pDDT;
PBYTE       PassBuffer;
USHORT      BufferSize;
PBYTE       OutputBuffer;
PBYTE       OutputBuffer2;
PBYTE       CommandBuffer;
PUSHORT     pCommandIndex;
USHORT      CommandSize;
SHORT       NewPosX;
PUSHORT     pHeadYPos;
lpDCI       DCIData;
USHORT      RasterLength;
PBYTE       InputBuffer;
                          */
USHORT prdp_Print360by360 (lpDDTType   pDDT,
                           PBYTE       PassBuffer,
                           USHORT      BufferSize,
                           PBYTE       OutputBuffer,
                           PBYTE       OutputBuffer2,
                           PBYTE       CommandBuffer,
                           PUSHORT     pCommandIndex,
                           USHORT      CommandSize,
                           SHORT       NewPosX,
                           PUSHORT     pHeadYPos,
                           lpDCI       DCIData,
                           USHORT      RasterLength,
                           PBYTE       InputBuffer)

{
   BYTE       i;                 /* Counter for for loop */
   BYTE       InitRastMask;      /* Initial mask of the input bytes */
   USHORT     BytesPerColumn;    /* Number of bytes per column */
   USHORT     PassLength;        /* Length of buffer to output */
   PBYTE      PassBufferPointer; /* Pointer to buffer */
   PBYTE      RasterPtr;         /* Pointer to input buffer 1 */
   PBYTE      RasterPtr2;        /* Pointer to input buffer 2 */
   PBYTE      InBuffer;          /* Pointer to buffer used to serialize data */
   USHORT     Count;             /* For loop counter */
   USHORT     Count2;            /* For loop counter */
   BYTE       RastMask;          /* Where we are in the current input byte */
   BYTE       OutMask;           /* Where we are in the current output byte */
   USHORT     Result;            /* return from print function */
   BOOL       ZeroByte;
   USHORT     NumberofZeroBytes;
   PUSHORT    ZeroBytePtr;
   PUSHORT    TempBytePtr;
   BOOL       PaddingDone;
   PBYTE      StartPassBuffPtr;   /* CON3201 */

   /**************************************************************************/
   /* Have two rows to print offset from each other by 1/360".  The first    */
   /* pass the mask will be 0x80 and the second 0x40.  This byte is shifted  */
   /* by two to get to every other byte.                                     */
   /**************************************************************************/
   StartPassBuffPtr = PassBuffer; /* Save starting address of PassBuffer     */
                                  /* so we can get offset later              */
   if ( prdg_AllocHeapItem( DCIData,
                            (USHORT)10080,
                            (PUSHORT *)&ZeroBytePtr ) != OK )
   {
      return( ERROR );
   }
   TempBytePtr = ZeroBytePtr;
   for (i = 0; i < 2; i++)
   {
      if (i == 0)
      {
         InitRastMask = 0x80;
      }
      else
      {
         InitRastMask = 0x40;
      }

      /***********************************************************************/
      /* Clear the buffer and initialize all the pointers to the buffers.    */
      /* These pointer are used to move along memory.  The original pointers */
      /* must remain in tact.                                                */
      /***********************************************************************/
      (VOID) prdu_memset ( (PBYTE) PassBuffer,
                           '\0',
                           BufferSize);
      (VOID) prdu_memset ( (PBYTE) ZeroBytePtr,
                           '\0',
                           (USHORT)10080 );
      BytesPerColumn = 3;
      PassLength = 0;
      PassBufferPointer = PassBuffer;
      RasterPtr = OutputBuffer;
      RasterPtr2 = OutputBuffer2;

      NumberofZeroBytes = 0;
      PaddingDone = FALSE;
      /***********************************************************************/
      /* Move along the input buffers until all bytes are processed.         */
      /***********************************************************************/
      for ( Count = 0; Count < RasterLength;
           Count += (2 * BytesPerColumn) )
      {
         /********************************************************************/
         /* Serialize the data from the two buffers into one so that they can*/
         /* be operated on sequentially without regard to which buffer to    */
         /* access.                                                          */
         /********************************************************************/
         if ( (NumberofZeroBytes > 1) && (!ZeroByte) )
         {
            *ZeroBytePtr++ = NumberofZeroBytes;
         }
         if (!ZeroByte)
         {
            NumberofZeroBytes = 0;
            if (PaddingDone)
            {
               NumberofZeroBytes++;
            }
         }
         ZeroByte = TRUE;
         InBuffer = InputBuffer;
         for (Count2 = 0; Count2 < 3; Count2++)
         {
            *(InBuffer++) = *(RasterPtr + Count2);
         }
         for (Count2 = 0; Count2 < 3; Count2++)
         {
            *(InBuffer++) = *(RasterPtr2 + Count2);
         }
         RasterPtr += BytesPerColumn;
         RasterPtr2 += BytesPerColumn;
         RastMask = InitRastMask;
         OutMask = 0x80;
         InBuffer = InputBuffer;

         /********************************************************************/
         /* Need to get the first three bytes from the six bytes by ORing    */
         /* into the input buffer.  The while loop will take eight passes    */
         /* to get all bits in the byte filled in.  This will continue for   */
         /* three bytes.                                                     */
         /********************************************************************/
         for (Count2 = 0; Count2 < BytesPerColumn; Count2++)
         {
            while (OutMask)
            {
               if (*InBuffer & RastMask)
               {
                  *PassBufferPointer |= OutMask;
                  ZeroByte = FALSE;
               }
               /************************************************************/
               /* PD00629 : If the byte is zero then skip the processing of*/
               /* it.                                                      */
               /************************************************************/
               else
               {
                  if ((*InBuffer) == 0)
                  {
                     OutMask = OutMask >> 4;
                     InBuffer++;
                     continue;
                  }
               }
               OutMask = OutMask >> 1;
               RastMask = RastMask >> 2;
               if (!RastMask)
               {
                  RastMask = InitRastMask;
                  InBuffer++;
               }
            }
            OutMask = 0x80;
            PassLength++;
            PassBufferPointer++;
         }
         /********************************************************************/
         /* If the end of the line is not reached, then output three zeros   */
         /* and bump all the pointers along.                                 */
         /********************************************************************/
         PaddingDone = FALSE;
         if ((Count + BytesPerColumn) != RasterLength)
         {
            RasterPtr += BytesPerColumn;
            RasterPtr2 += BytesPerColumn;
            for (Count2 = 0; Count2 < BytesPerColumn; Count2++)
            {
               *PassBufferPointer++ = 0;
            }
            PaddingDone = TRUE;
            PassLength += BytesPerColumn;
         }
         if (ZeroByte)
         {
            NumberofZeroBytes++;
            if (PaddingDone)
            {
               NumberofZeroBytes++;
            }
            if ((NumberofZeroBytes == 2) || (NumberofZeroBytes == 3))
            {
/*             *ZeroBytePtr++ = (OFFSETOF(PassBufferPointer) -       CON3201 */
               *ZeroBytePtr++ = (USHORT)((PassBufferPointer - StartPassBuffPtr)
                                 - (NumberofZeroBytes * 3)) ;
            }
         }
      }

      if (NumberofZeroBytes > 1)
      {
         *ZeroBytePtr++ = NumberofZeroBytes;
      }

      /***********************************************************************/
      /*  Output the pass and put the printhead to the left margin.          */
      /***********************************************************************/
      if ( (Result = prdp_PrintRasterPass(
                         DCIData,
                         PassLength,
                         (PBYTE)PassBuffer,
                         BytesPerColumn,
                         TempBytePtr) ) != OK )
      {
         TRACE4(TFUNC, "Error in Raster", FNULL, 0);
         return( Result );
      }

      ZeroBytePtr = TempBytePtr;
      if ( (Result = prdp_AddString (
                         EST_CARRIAGE_RETURN,
                         USE_GLOBAL_TABLE,
                         FNULL,
                         CommandBuffer,
                         pCommandIndex,
                         CommandSize,
                         DCIData )) != OK)
      {
         return( ERROR );
      }

      prdp_AddHorizMoveString( 0,
                               NewPosX,
                               CommandBuffer,
                               pCommandIndex,
                               CommandSize,
                               DCIData );

      if ( (Result = prdp_PrintMemory ( CommandBuffer,
                                        *pCommandIndex,
                                        DCIData ) ) != OK )
      {
         return( Result );
      }

      *pCommandIndex = 0;

      /***********************************************************************/
      /* Do the same as above except for the odd bytes.  Therefore, zeroes   */
      /* have to be output in the even slots of the raster.                  */
      /***********************************************************************/
      (VOID) prdu_memset ( (PBYTE) PassBuffer,
                           '\0',
                           BufferSize);
      (VOID) prdu_memset ( (PBYTE) ZeroBytePtr,
                           '\0',
                           (USHORT) 10080 );
      PassLength = 0;
      RasterPtr = OutputBuffer;
      RasterPtr2 = OutputBuffer2;
      PassBufferPointer = PassBuffer;
      NumberofZeroBytes = 0;
      for ( Count = BytesPerColumn; Count < RasterLength;
            Count += (2 * BytesPerColumn) )
      {
         if ((NumberofZeroBytes > 1) && (!ZeroByte))
         {
            *ZeroBytePtr++ = NumberofZeroBytes;
            NumberofZeroBytes = 0;
         }
         if (NumberofZeroBytes == 1)
         {
            NumberofZeroBytes = 0;
         }
         ZeroByte = TRUE;
         RasterPtr += BytesPerColumn;
         RasterPtr2 += BytesPerColumn;
         for (Count2 = 0; Count2 < BytesPerColumn; Count2++)
         {
            *PassBufferPointer++ = 0;
         }
         NumberofZeroBytes++;
         PassLength += BytesPerColumn;
         InBuffer = InputBuffer;
         for (Count2 = 0; Count2 < 3; Count2++)
         {
            *(InBuffer++) = *(RasterPtr + Count2);
         }
         for (Count2 = 0; Count2 < 3; Count2++)
         {
            *(InBuffer++) = *(RasterPtr2 + Count2);
         }
         RasterPtr += BytesPerColumn;
         RasterPtr2 += BytesPerColumn;
         RastMask = InitRastMask;
         OutMask = 0x80;
         InBuffer = InputBuffer;
         for (Count2 = 0; Count2 < BytesPerColumn; Count2++)
         {
            while (OutMask)
            {
               if (*InBuffer & RastMask)
               {
                  *PassBufferPointer |= OutMask;
                  ZeroByte = FALSE;
               }
               /************************************************************/
               /* PD00629 : Skip the byte if it is zero.                   */
               /************************************************************/
               else
               {
                  if ((*InBuffer) == 0)
                  {
                     OutMask = OutMask >> 4;
                     InBuffer++;
                     continue;
                  }
               }
               OutMask = OutMask >> 1;
               RastMask = RastMask >> 2;
               if (!RastMask)
               {
                  RastMask = InitRastMask;
                  InBuffer++;
               }
            }
            OutMask = 0x80;
            PassLength++;
            PassBufferPointer++;
         }
         if (ZeroByte)
         {
            NumberofZeroBytes++;
            if (NumberofZeroBytes == 2)
            {
/*             *ZeroBytePtr++ = (OFFSETOF(PassBufferPointer) - 6);    CON3201 */
               *ZeroBytePtr++ = (USHORT)((PassBufferPointer - StartPassBuffPtr)
                                 - 6);
            }
         }
      }
      if (NumberofZeroBytes > 1)
      {
         *ZeroBytePtr++ = NumberofZeroBytes;
      }

      if ( (Result = prdp_PrintRasterPass(
                         DCIData,
                         PassLength,
                         (PBYTE)PassBuffer,
                         BytesPerColumn,
                         TempBytePtr) ) != OK )
      {
         TRACE4(TFUNC, "Error in Raster", FNULL, 0);
         return( Result );
      }
      ZeroBytePtr = TempBytePtr;
      /***********************************************************************/
      /* If this is the first pass through the loop then we have to move     */
      /* down 1/360" so that the odd bits will line up correctly.  Originally*/
      /* I had this for either case, but the printer did not like two ESC J s*/
      /* in a row and would sometimes get screwed up.  So this check must    */
      /* remain.                                                             */
      /***********************************************************************/
      if (i == 0)
      {
         if ( (Result = prdp_AddString (
                            EST_CARRIAGE_RETURN,
                            USE_GLOBAL_TABLE,
                            FNULL,
                            CommandBuffer,
                            pCommandIndex,
                            CommandSize,
                            DCIData )) != OK)
         {
            return( ERROR );
         }

         prdp_AddHorizMoveString( 0,
                                  NewPosX,
                                  CommandBuffer,
                                  pCommandIndex,
                                  CommandSize,
                                  DCIData );

         *(CommandBuffer + *pCommandIndex) = 0x1B;
         *(CommandBuffer + *pCommandIndex + 1) = 0x4A;
         *(CommandBuffer + *pCommandIndex + 2) = 0x01;
         *pCommandIndex += 3;

         /********************************************************************/
         /* Be sure to keep track of the head position.                      */
         /********************************************************************/
         *pHeadYPos = *pHeadYPos - 1;

         if ( (Result = prdp_PrintMemory ( CommandBuffer,
                                           *pCommandIndex,
                                           DCIData ) ) != OK )
         {
            return( Result );
         }

         *pCommandIndex = 0;
      }

   }
   (void)prdg_FreeHeapItem( DCIData,
                            (USHORT)10080,
                            (PUSHORT)ZeroBytePtr );
   return(OK);
}

/******************************************************************************/
/*  FUNCTION: prdp_Print360by180                                              */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function outputs one 24 bit deep 360x180 scanline pass to the        */
/*  printer by doing every byte for two passes to produce a simulated 360x180 */
/******************************************************************************/
/* CON3201
USHORT  prdp_Print360by180 (PassBuffer, OutputBuffer, CommandBuffer,
                                    pCommandIndex, CommandSize, NewPosX,
                                    DCIData, RasterLength, BytesPerColumn)

PBYTE       PassBuffer;
PBYTE       OutputBuffer;
PBYTE       CommandBuffer;
PUSHORT     pCommandIndex;
USHORT      CommandSize;
SHORT       NewPosX;
lpDCI       DCIData;
USHORT      RasterLength;
USHORT      BytesPerColumn;
                           */
USHORT prdp_Print360by180 ( PBYTE       PassBuffer,
                            PBYTE       OutputBuffer,
                            PBYTE       CommandBuffer,
                            PUSHORT     pCommandIndex,
                            USHORT      CommandSize,
                            SHORT       NewPosX,
                            lpDCI       DCIData,
                            USHORT      RasterLength,
                            USHORT      BytesPerColumn)

{
   USHORT        PassLength;           /* Length of buffer to output */
   PBYTE         PassBufferPointer;    /* Pointer to the output buffer */
   PBYTE         RasterPtr;            /* Pointer to the input buffer */
   USHORT        Count;                /* For loop counter */
   USHORT        Row;                  /* For loop counter */
   USHORT        Result;               /* Return from print functions */
   USHORT        Count2;               /* For loop counter */
   BOOL          ZeroByte;
   USHORT        NumberofZeroBytes;
   PUSHORT       ZeroBytePtr;
   PUSHORT       TempBytePtr;
   BOOL          PaddingDone;
   PBYTE         StartPassBuffPtr;     /* CON3201 */

   PassLength = 0;
   StartPassBuffPtr = PassBuffer;   /* CON3201 save PassBuffer so we can get */
                                    /* offset later                          */
   PassBufferPointer = PassBuffer;
   RasterPtr = OutputBuffer;

   if ( prdg_AllocHeapItem( DCIData,
                            (USHORT)10080,
                            (PUSHORT *)&ZeroBytePtr ) != OK )
   {
      return( ERROR );
   }

   TempBytePtr = ZeroBytePtr;
   (VOID) prdu_memset ( (PBYTE) ZeroBytePtr,
                        '\0',
                        (USHORT)10080 );

   NumberofZeroBytes = 0;
   PaddingDone = FALSE;
   /**************************************************************************/
   /* Until the end of the line is reached, put the even rows into the buffer*/
   /* to output.  If this is 360x180, also need to put zeroes between each   */
   /* row since we are printing 360x180.                                     */
   /**************************************************************************/
   for ( Count = 0; Count < RasterLength;
        Count += (2 * BytesPerColumn) )
   {
      if ( (NumberofZeroBytes > 1) && (!ZeroByte) )
      {
         *ZeroBytePtr++ = NumberofZeroBytes;
      }
      if (!ZeroByte)
      {
         NumberofZeroBytes = 0;
         if (PaddingDone)
         {
            NumberofZeroBytes++;
         }
      }
      ZeroByte = TRUE;

      for (Row = 0; Row < BytesPerColumn; Row++)
      {
         if (*RasterPtr != 0)
         {
            ZeroByte = FALSE;
         }
         *PassBufferPointer++ = *RasterPtr++;
      }
      PassLength += BytesPerColumn;
      PaddingDone = FALSE;
      if ((Count + BytesPerColumn) != RasterLength)
      {
         RasterPtr += BytesPerColumn;
         if (BytesPerColumn == 3)
         {
            for (Count2 = 0; Count2 < BytesPerColumn; Count2++)
            {
               *PassBufferPointer++ = 0;
            }
            PaddingDone = TRUE;
            PassLength += BytesPerColumn;
         }
      }
      if (ZeroByte)
      {
         NumberofZeroBytes++;
         if (PaddingDone)
         {
            NumberofZeroBytes++;
         }
         if ((NumberofZeroBytes == 2) || ((NumberofZeroBytes == 3) &&
              PaddingDone))
         {
/*          *ZeroBytePtr++ = (OFFSETOF(PassBufferPointer) -          CON3201 */
            *ZeroBytePtr++ = (USHORT)((PassBufferPointer - StartPassBuffPtr)
                             - (NumberofZeroBytes * BytesPerColumn));
         }
      }
   }

   if (NumberofZeroBytes > 1)
   {
      *ZeroBytePtr++ = NumberofZeroBytes;
   }

   /*************************************************************************/
   /* Output the first pass and reset the printhead to the left margin.  If */
   /* the resolution is 240x72, need to move over one pel by outputing a    */
   /* 240x72 scanline one pel wide.                                         */
   /*************************************************************************/

   if ( (Result = prdp_PrintRasterPass(
                      DCIData,
                      PassLength,
                      (PBYTE)PassBuffer,
                      BytesPerColumn,
                      TempBytePtr ) ) != OK )
   {
      TRACE4(TFUNC, "Error in Raster", FNULL, 0);
      return( Result );
   }
   ZeroBytePtr = TempBytePtr;

   if ( (Result = prdp_AddString (
                      EST_CARRIAGE_RETURN,
                      USE_GLOBAL_TABLE,
                      FNULL,
                      CommandBuffer,
                      pCommandIndex,
                      CommandSize,
                      DCIData )) != OK)
   {
      return( ERROR );
   }

   prdp_AddHorizMoveString( 0,
                            NewPosX,
                            CommandBuffer,
                            pCommandIndex,
                            CommandSize,
                            DCIData );

   if ( (Result = prdp_PrintMemory ( CommandBuffer,
                                     *pCommandIndex,
                                     DCIData ) ) != OK )
   {
      return( Result );
   }

   *pCommandIndex = 0;

   if (BytesPerColumn != 3)
   {
      PassBufferPointer = PassBuffer;
      for (Count = 0; Count < BytesPerColumn; Count++)
      {
         *PassBufferPointer++ = 0;
      }

      if ( (Result = prdp_PrintRaster(
                         DCIData,
                         BytesPerColumn,
                         (PBYTE)PassBuffer) ) != OK )
      {
         TRACE4(TFUNC, "Error in Raster", FNULL, 0);
         return( Result );
      }
   }

   (VOID) prdu_memset ( (PBYTE) ZeroBytePtr,
                        '\0',
                        (USHORT) 10080 );
   /*************************************************************************/
   /* Do the same as above except for odd rows.                             */
   /*************************************************************************/
   PassBufferPointer = PassBuffer;
   RasterPtr = OutputBuffer;
   PassLength = 0;
   NumberofZeroBytes = 0;
   for (Count = BytesPerColumn; Count < RasterLength;
        Count += (2 * BytesPerColumn) )
   {
      if ((NumberofZeroBytes > 1) && (!ZeroByte))
      {
         *ZeroBytePtr++ = NumberofZeroBytes;
         NumberofZeroBytes = 0;
      }
      if ( (NumberofZeroBytes == 1) && (BytesPerColumn == 3) )
      {
         NumberofZeroBytes = 0;
      }
      ZeroByte = TRUE;

      RasterPtr += BytesPerColumn;
      PaddingDone = FALSE;
      if (BytesPerColumn == 3)
      {
         for (Count2 = 0; Count2 < BytesPerColumn; Count2++)
         {
            *PassBufferPointer++ = 0;
         }
         NumberofZeroBytes++;
         PassLength += BytesPerColumn;
         PaddingDone = TRUE;
      }
      for (Row = 0; Row < BytesPerColumn; Row++)
      {
         if (*RasterPtr != 0)
         {
            ZeroByte = FALSE;
         }
         *PassBufferPointer++ = *RasterPtr++;
      }
      PassLength += BytesPerColumn;
      if (ZeroByte)
      {
         NumberofZeroBytes++;
         if ((NumberofZeroBytes == 1) || ((NumberofZeroBytes == 2) &&
              PaddingDone))
         {
// CON3201  *ZeroBytePtr++ = (OFFSETOF(PassBufferPointer) - (BytesPerColumn *
            *ZeroBytePtr++ = (USHORT)((PassBufferPointer - StartPassBuffPtr)
                                      - (BytesPerColumn * NumberofZeroBytes));
         }
      }
   }
   if (NumberofZeroBytes > 1)
   {
      *ZeroBytePtr++ = NumberofZeroBytes;
   }

   if ( (Result = prdp_PrintRasterPass(
                      DCIData,
                      PassLength,
                      (PBYTE)PassBuffer,
                      BytesPerColumn,
                      TempBytePtr ) ) != OK )
   {
      TRACE4(TFUNC, "Error in Raster", FNULL, 0);
      return( Result );
   }
   ZeroBytePtr = TempBytePtr;
   (void)prdg_FreeHeapItem( DCIData,
                            (USHORT)10080,
                            (PUSHORT)ZeroBytePtr );
   return(OK);
}
/* CON3201
USHORT prdp_PrintRasterPass ( DCIData,
                                     RasterLength,
                                     RasterPtr,
                                     BytesPerColumn,
                                     ZeroBytePtr)

lpDCI           DCIData;
USHORT          RasterLength;
PBYTE           RasterPtr;
USHORT          BytesPerColumn;
PUSHORT         ZeroBytePtr;
                             */

SHORT prdp_PrintRasterPass (lpDCI           DCIData,    /* CON3203 */
                             USHORT          RasterLength,
                             PBYTE           RasterPtr,
                             USHORT          BytesPerColumn,
                             PUSHORT         ZeroBytePtr)

{
#define TFUNC "prdp_PrintRasterPass"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT      Result;
    lpPDBI      PDBInst;               /* pointer to PDB instance     */
    USHORT      BytesWritten;          /* number of bytes prtwritten  */
    lpDDTType   pDDT;                  /* Pointer to DDT in PDB       */
    USHORT      AmountofMove;
    USHORT      RawRasterLength;
    USHORT      AlignLength;
    USHORT      Adjustment;
    PBYTE       StartRastPtr;          /* CON3201 */

    TRACE4(TFUNC, "Entry", FNULL, 0);
    TRACE4(TFUNC, "RasterPtr", &RasterPtr, 1);
    TRACE4(TFUNC, "RasterLength", &RasterLength, 1);

    StartRastPtr = RasterPtr; /* CON3201 save RasterPtr so we can get offset */
                              /*         later                               */
    PDBInst = DCIData->DCIPdbInstance;
    pDDT = &PDBInst->DDT;

    do
    {
       if (*ZeroBytePtr == 0)
       {
          RawRasterLength = RasterLength;
          AmountofMove = 0;
       }
       else
       {
          while ((*(ZeroBytePtr + 1)) < 36)
          {
             ZeroBytePtr++;
             ZeroBytePtr++;
             if (*ZeroBytePtr == 0)
             {
                RawRasterLength = RasterLength;
                AmountofMove = 0;
                break;
             }
          }
          if ((*(ZeroBytePtr + 1)) >= 36)
          {
             if (BytesPerColumn == 3)
             {
                if (AmountofMove = ((*(ZeroBytePtr + 1)) % 3))
                {
// CON3201         AlignLength = (*ZeroBytePtr - OFFSETOF(RasterPtr)) % 9;
                   AlignLength = (*ZeroBytePtr - (USHORT)(RasterPtr -
                                                       StartRastPtr)) % 9;
                   if (AlignLength > AmountofMove)
                   {
                      Adjustment = AlignLength * 3;
                   }
                   else
                   {
                      Adjustment = AmountofMove * 3;
                      AlignLength = Adjustment % 9;
                      if (AlignLength)
                      {
                         Adjustment = Adjustment + AlignLength * 3;
                      }
                   }
// CON3201         RawRasterLength = (((*ZeroBytePtr++ - OFFSETOF(RasterPtr)) /
// CON3201                              9) * 9) + Adjustment;
                   RawRasterLength = (((*ZeroBytePtr++ - (USHORT)(RasterPtr
                   - StartRastPtr)) / 9) * 9) + Adjustment;
                   if (Adjustment > *ZeroBytePtr)
                   {
                      AmountofMove = 0;
                   }
                   else
                   {
                      AmountofMove = (*ZeroBytePtr - (Adjustment /
                                      3)) / 3;
                   }
                }
                else
                {
// CON3201         AlignLength = (*ZeroBytePtr - OFFSETOF(RasterPtr)) % 9;
                   AlignLength = (*ZeroBytePtr - (USHORT)(RasterPtr -
                                                     StartRastPtr)) % 9;
                   AlignLength = AlignLength * 3;
// CON3201         RawRasterLength = (((*ZeroBytePtr++ - OFFSETOF(RasterPtr)) /
// CON3201                              9) * 9) + AlignLength;
                   RawRasterLength = (((*ZeroBytePtr++ - (USHORT)(RasterPtr
                                      - StartRastPtr)) / 9) * 9) + AlignLength;
                   if (AlignLength > *ZeroBytePtr)
                   {
                      AmountofMove = 0;
                   }
                   else
                   {
                      AmountofMove = (*ZeroBytePtr - (AlignLength /
                                      3)) / 3;
                   }
                }
                ZeroBytePtr++;
             }
             else
             {
                RawRasterLength = RasterLength;
                AmountofMove = 0;
             }
          }
       }
       /******************************************************************/
       /* The code takes advantage of the fact that the number of        */
       /* bytes is supplied as two parameters, with the low byte first.  */
       /*                                                                */
       /* Length of data to be passed to the printer is length+1 for     */
       /* high density                                                   */
       /******************************************************************/
       if ( (pDDT->DDTRasterMode->VertLinePels == 24) && RawRasterLength )
       {
           RawRasterLength++;

           if ( (Result = prdp_PrintSimple( DCIData,
                                            USE_PRINTER_TABLE,
                                            PDBInst->RasterMode,
                                            (PBYTE)&RawRasterLength )) != OK )
           {
               return( Result );
           }

           RawRasterLength--;
       }
       else
       {
          if (RawRasterLength)
          {
             /*****************************************************************/
             /* Always output 120x72 graphics command.                        */
             /*****************************************************************/

             if ( (Result = prdp_PrintSimple( DCIData,
                                              USE_PRINTER_TABLE,
                                              DCT_RASTER_MODE_2,
                                              (PBYTE)&RawRasterLength )) != OK )
             {
                 return( Result );
             }
          }
       }

       /******************************************************************/
       /* If this is an Indirect RAW DC then ouput string to spool       */
       /* file rather than to printer.                                   */
       /******************************************************************/
       if ( (DCIData->Flags & QUEUED_RAW) && (RawRasterLength) )
       {
           Result = SplQmWrite ((HSPL)DCIData->DCISplHandle,
                                (ULONG) RawRasterLength,
                                (PBYTE) RasterPtr);

           if ( Result != OK )
           {
              OutputString("Spool write in pRaster failed\n");
              return (ERROR_NEG);
           }

       }
       else
       {
          if (RawRasterLength)
          {
             /*****************************************************************/
             /* Now output the raster to the printer.  If Write produced an   */
             /* error, then handle it                                         */
             /*****************************************************************/
             OutputString("before PrtWrite\n");

             Result = prdn_PrtWrite( DCIData,
                                     RasterPtr,
                                     RawRasterLength,
                                     PDBInst,
                                     BytesWritten );

             OutputString("after PrtWrite\n");

             if ( Result != OK )
             {
                 /******************************************************/
                 /* ERROR, ERR_ABORT or ERR_PURGE                      */
                 /******************************************************/
                 return( Result );
             }
          }
       }
       RasterLength -= RawRasterLength;
       RasterPtr += RawRasterLength;

       if (AmountofMove)
       {
          if ( (Result = prdp_PrintSimple( DCIData,
                                           USE_PRINTER_TABLE,
                                           DCT_ROUGH_MOVE_RIGHT,
                                           (PBYTE)&AmountofMove )) != OK )
          {
              return (Result);
          }
          RasterLength -= AmountofMove * 9;
          RasterPtr += AmountofMove * 9;
       }

    }
    while (RasterLength);

    return(OK);
}
#undef TFUNC
